summaryrefslogtreecommitdiff
path: root/chromium/components
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components')
-rw-r--r--chromium/components/about_handler.gypi (renamed from chromium/components/url_fixer.gypi)20
-rw-r--r--chromium/components/app_modal.gypi5
-rw-r--r--chromium/components/audio_modem.gypi1
-rw-r--r--chromium/components/autofill.gypi24
-rw-r--r--chromium/components/autofill_strings.grdp27
-rw-r--r--chromium/components/bookmarks.gypi6
-rw-r--r--chromium/components/bubble.gypi43
-rw-r--r--chromium/components/certificate_reporting.gypi57
-rw-r--r--chromium/components/certificate_transparency.gypi26
-rw-r--r--chromium/components/chrome_apps/chrome_apps_resources.grd19
-rw-r--r--chromium/components/chrome_apps/webstore_widget/app/compiled_resources.gyp2
-rw-r--r--chromium/components/component_updater.gypi5
-rw-r--r--chromium/components/components.gyp26
-rw-r--r--chromium/components/components_browsertests.isolate3
-rw-r--r--chromium/components/components_chromium_strings.grd170
-rw-r--r--chromium/components/components_google_chrome_strings.grd171
-rw-r--r--chromium/components/components_resources.gyp41
-rw-r--r--chromium/components/components_strings.grd40
-rw-r--r--chromium/components/components_strings.gyp21
-rw-r--r--chromium/components/components_tests.gyp401
-rw-r--r--chromium/components/components_unittests.isolate4
-rw-r--r--chromium/components/compression.gypi24
-rw-r--r--chromium/components/content_settings.gypi25
-rw-r--r--chromium/components/crash.gypi584
-rw-r--r--chromium/components/cronet.gypi42
-rw-r--r--chromium/components/cronet/cronet_static.gypi5
-rw-r--r--chromium/components/crx_file.gypi1
-rw-r--r--chromium/components/data_reduction_proxy.gypi4
-rw-r--r--chromium/components/data_use_measurement.gypi33
-rw-r--r--chromium/components/device_event_log/device_event_log_impl.cc2
-rw-r--r--chromium/components/device_event_log/device_event_log_impl_unittest.cc11
-rw-r--r--chromium/components/devtools_discovery/devtools_discovery_manager.cc2
-rw-r--r--chromium/components/devtools_discovery/devtools_discovery_manager.h2
-rw-r--r--chromium/components/devtools_http_handler/BUILD.gn1
-rw-r--r--chromium/components/devtools_http_handler/devtools_http_handler.cc34
-rw-r--r--chromium/components/devtools_http_handler/devtools_http_handler_delegate.h9
-rw-r--r--chromium/components/devtools_http_handler/devtools_http_handler_unittest.cc5
-rw-r--r--chromium/components/devtools_service/BUILD.gn4
-rw-r--r--chromium/components/devtools_service/devtools_agent_host.cc23
-rw-r--r--chromium/components/devtools_service/devtools_agent_host.h16
-rw-r--r--chromium/components/devtools_service/devtools_http_server.cc40
-rw-r--r--chromium/components/devtools_service/devtools_http_server.h1
-rw-r--r--chromium/components/devtools_service/devtools_registry_impl.cc9
-rw-r--r--chromium/components/devtools_service/devtools_registry_impl.h2
-rw-r--r--chromium/components/devtools_service/devtools_service.cc6
-rw-r--r--chromium/components/devtools_service/devtools_service.h9
-rw-r--r--chromium/components/devtools_service/devtools_service_delegate.cc3
-rw-r--r--chromium/components/devtools_service/public/interfaces/devtools_service.mojom17
-rw-r--r--chromium/components/dom_distiller.gypi81
-rw-r--r--chromium/components/dom_distiller_strings.grdp7
-rw-r--r--chromium/components/domain_reliability.gypi1
-rw-r--r--chromium/components/drive.gypi176
-rw-r--r--chromium/components/enhanced_bookmarks.gypi8
-rw-r--r--chromium/components/error_page.gypi1
-rw-r--r--chromium/components/error_page/common/net_error_info.cc41
-rw-r--r--chromium/components/error_page/common/net_error_info.h16
-rw-r--r--chromium/components/error_page/renderer/BUILD.gn17
-rw-r--r--chromium/components/error_page/renderer/DEPS2
-rw-r--r--chromium/components/error_page/renderer/net_error_helper_core.cc150
-rw-r--r--chromium/components/error_page/renderer/net_error_helper_core.h33
-rw-r--r--chromium/components/error_page/renderer/net_error_helper_core_unittest.cc735
-rw-r--r--chromium/components/favicon.gypi8
-rw-r--r--chromium/components/flags_ui.gypi26
-rw-r--r--chromium/components/flags_ui_strings.grdp58
-rw-r--r--chromium/components/gcm_driver.gypi92
-rw-r--r--chromium/components/google.gypi5
-rw-r--r--chromium/components/history.gypi1
-rw-r--r--chromium/components/html_viewer/html_viewer_resources.grd10
-rw-r--r--chromium/components/infobars.gypi8
-rw-r--r--chromium/components/invalidation.gypi23
-rw-r--r--chromium/components/keyed_service/DEPS8
-rw-r--r--chromium/components/keyed_service/OWNERS2
-rw-r--r--chromium/components/keyed_service/README9
-rw-r--r--chromium/components/keyed_service/content/BUILD.gn44
-rw-r--r--chromium/components/keyed_service/content/DEPS4
-rw-r--r--chromium/components/keyed_service/content/browser_context_dependency_manager.cc100
-rw-r--r--chromium/components/keyed_service/content/browser_context_dependency_manager.h106
-rw-r--r--chromium/components/keyed_service/content/browser_context_dependency_manager_unittest.cc171
-rw-r--r--chromium/components/keyed_service/content/browser_context_keyed_base_factory.cc90
-rw-r--r--chromium/components/keyed_service/content/browser_context_keyed_base_factory.h121
-rw-r--r--chromium/components/keyed_service/content/browser_context_keyed_service_factory.cc124
-rw-r--r--chromium/components/keyed_service/content/browser_context_keyed_service_factory.h148
-rw-r--r--chromium/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.cc37
-rw-r--r--chromium/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h35
-rw-r--r--chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.cc121
-rw-r--r--chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h144
-rw-r--r--chromium/components/keyed_service/core/BUILD.gn48
-rw-r--r--chromium/components/keyed_service/core/dependency_graph.cc159
-rw-r--r--chromium/components/keyed_service/core/dependency_graph.h67
-rw-r--r--chromium/components/keyed_service/core/dependency_graph_unittest.cc158
-rw-r--r--chromium/components/keyed_service/core/dependency_manager.cc143
-rw-r--r--chromium/components/keyed_service/core/dependency_manager.h106
-rw-r--r--chromium/components/keyed_service/core/dependency_node.h16
-rw-r--r--chromium/components/keyed_service/core/keyed_service.cc11
-rw-r--r--chromium/components/keyed_service/core/keyed_service.h27
-rw-r--r--chromium/components/keyed_service/core/keyed_service_base_factory.cc136
-rw-r--r--chromium/components/keyed_service/core/keyed_service_base_factory.h197
-rw-r--r--chromium/components/keyed_service/core/keyed_service_export.h29
-rw-r--r--chromium/components/keyed_service/core/keyed_service_factory.cc139
-rw-r--r--chromium/components/keyed_service/core/keyed_service_factory.h99
-rw-r--r--chromium/components/keyed_service/core/keyed_service_shutdown_notifier.cc20
-rw-r--r--chromium/components/keyed_service/core/keyed_service_shutdown_notifier.h39
-rw-r--r--chromium/components/keyed_service/core/refcounted_keyed_service.cc33
-rw-r--r--chromium/components/keyed_service/core/refcounted_keyed_service.h72
-rw-r--r--chromium/components/keyed_service/core/refcounted_keyed_service_factory.cc131
-rw-r--r--chromium/components/keyed_service/core/refcounted_keyed_service_factory.h96
-rw-r--r--chromium/components/keyed_service/core/service_access_type.h34
-rw-r--r--chromium/components/keyed_service/ios/DEPS3
-rw-r--r--chromium/components/keyed_service/ios/OWNERS3
-rw-r--r--chromium/components/keyed_service/ios/browser_state_context_converter.cc28
-rw-r--r--chromium/components/keyed_service/ios/browser_state_context_converter.h55
-rw-r--r--chromium/components/keyed_service/ios/browser_state_dependency_manager.cc67
-rw-r--r--chromium/components/keyed_service/ios/browser_state_dependency_manager.h91
-rw-r--r--chromium/components/keyed_service/ios/browser_state_keyed_service_factory.cc139
-rw-r--r--chromium/components/keyed_service/ios/browser_state_keyed_service_factory.h140
-rw-r--r--chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.cc151
-rw-r--r--chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.h145
-rw-r--r--chromium/components/memory_pressure.gypi31
-rw-r--r--chromium/components/message_port.gypi2
-rw-r--r--chromium/components/metrics.gypi114
-rw-r--r--chromium/components/mime_util/mime_util.cc21
-rw-r--r--chromium/components/nacl.gyp3
-rw-r--r--chromium/components/nacl_helper_nonsfi_unittests.isolate1
-rw-r--r--chromium/components/nacl_loader_unittests.isolate4
-rw-r--r--chromium/components/nacl_nonsfi.gyp3
-rw-r--r--chromium/components/navigation_interception.gypi4
-rw-r--r--chromium/components/net_log.gypi31
-rw-r--r--chromium/components/offline_pages.gypi36
-rw-r--r--chromium/components/omnibox.gypi34
-rw-r--r--chromium/components/omnibox_strings.grdp4
-rw-r--r--chromium/components/open_from_clipboard.gypi23
-rw-r--r--chromium/components/open_from_clipboard_strings.grdp6
-rw-r--r--chromium/components/page_load_metrics.gypi66
-rw-r--r--chromium/components/password_manager.gypi33
-rw-r--r--chromium/components/pdf_strings.grdp43
-rw-r--r--chromium/components/policy.gypi27
-rw-r--r--chromium/components/policy/policy_browser.gypi15
-rw-r--r--chromium/components/policy/policy_common.gypi4
-rw-r--r--chromium/components/policy/resources/policy_templates.grd309
-rw-r--r--chromium/components/policy_strings.grdp15
-rw-r--r--chromium/components/precache.gypi1
-rw-r--r--chromium/components/pref_registry.gypi6
-rw-r--r--chromium/components/pref_registry/BUILD.gn32
-rw-r--r--chromium/components/pref_registry/DEPS3
-rw-r--r--chromium/components/pref_registry/OWNERS4
-rw-r--r--chromium/components/pref_registry/README6
-rw-r--r--chromium/components/pref_registry/pref_registry_syncable.cc49
-rw-r--r--chromium/components/pref_registry/pref_registry_syncable.h89
-rw-r--r--chromium/components/pref_registry/testing_pref_service_syncable.cc70
-rw-r--r--chromium/components/pref_registry/testing_pref_service_syncable.h38
-rw-r--r--chromium/components/printing.gypi15
-rw-r--r--chromium/components/printing/browser/BUILD.gn16
-rw-r--r--chromium/components/printing/browser/print_manager.cc69
-rw-r--r--chromium/components/printing/browser/print_manager.h68
-rw-r--r--chromium/components/printing/browser/print_manager_utils.cc41
-rw-r--r--chromium/components/printing/browser/print_manager_utils.h21
-rw-r--r--chromium/components/printing/common/BUILD.gn2
-rw-r--r--chromium/components/printing/common/print_messages.h8
-rw-r--r--chromium/components/printing/renderer/BUILD.gn4
-rw-r--r--chromium/components/printing/renderer/print_web_view_helper.cc117
-rw-r--r--chromium/components/printing/renderer/print_web_view_helper.h2
-rw-r--r--chromium/components/printing/renderer/print_web_view_helper_linux.cc30
-rw-r--r--chromium/components/printing/renderer/print_web_view_helper_mac.mm3
-rw-r--r--chromium/components/printing/renderer/print_web_view_helper_pdf_win.cc62
-rw-r--r--chromium/components/proximity_auth.gypi69
-rw-r--r--chromium/components/proxy_config.gypi11
-rw-r--r--chromium/components/rappor.gypi1
-rw-r--r--chromium/components/resources/BUILD.gn38
-rw-r--r--chromium/components/resources/OWNERS5
-rw-r--r--chromium/components/resources/about_ui_resources.grdp5
-rw-r--r--chromium/components/resources/autofill_scaled_resources.grdp13
-rw-r--r--chromium/components/resources/components_resources.grd6
-rw-r--r--chromium/components/resources/components_scaled_resources.grd2
-rw-r--r--chromium/components/resources/default_100_percent/autofill/mac_contacts_icon.pngbin875 -> 0 bytes
-rw-r--r--chromium/components/resources/default_100_percent/omnibox/ios/location_bar_http.pngbin0 -> 2833 bytes
-rw-r--r--chromium/components/resources/default_100_percent/omnibox/location_bar_http.pngbin0 -> 306 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/mac_contacts_icon.pngbin2335 -> 0 bytes
-rw-r--r--chromium/components/resources/default_200_percent/omnibox/ios/location_bar_http.pngbin0 -> 2912 bytes
-rw-r--r--chromium/components/resources/default_200_percent/omnibox/location_bar_http.pngbin0 -> 393 bytes
-rw-r--r--chromium/components/resources/default_300_percent/omnibox/ios/location_bar_http.pngbin0 -> 3083 bytes
-rw-r--r--chromium/components/resources/flags_ui_resources.grdp5
-rw-r--r--chromium/components/resources/gcm_driver_resources.grdp6
-rw-r--r--chromium/components/resources/material_100_percent/omnibox/location_bar_http.pngbin0 -> 101 bytes
-rw-r--r--chromium/components/resources/material_100_percent/omnibox/omnibox_extension_app.pngbin0 -> 178 bytes
-rw-r--r--chromium/components/resources/material_100_percent/omnibox/omnibox_http.pngbin0 -> 101 bytes
-rw-r--r--chromium/components/resources/material_100_percent/omnibox/omnibox_search.pngbin0 -> 170 bytes
-rw-r--r--chromium/components/resources/material_200_percent/omnibox/location_bar_http.pngbin0 -> 127 bytes
-rw-r--r--chromium/components/resources/material_200_percent/omnibox/omnibox_extension_app.pngbin0 -> 228 bytes
-rw-r--r--chromium/components/resources/material_200_percent/omnibox/omnibox_http.pngbin0 -> 127 bytes
-rw-r--r--chromium/components/resources/material_200_percent/omnibox/omnibox_search.pngbin0 -> 318 bytes
-rw-r--r--chromium/components/resources/net_log_resources.grdp5
-rw-r--r--chromium/components/resources/omnibox_scaled_resources.grdp2
-rw-r--r--chromium/components/resources/proximity_auth_resources.grdp4
-rw-r--r--chromium/components/resources/security_interstitials_resources.grdp5
-rw-r--r--chromium/components/resources/sync_driver_resources.grdp14
-rw-r--r--chromium/components/rlz.gypi38
-rw-r--r--chromium/components/safe_json.gypi53
-rw-r--r--chromium/components/scheduler/BUILD.gn31
-rw-r--r--chromium/components/scheduler/DEPS1
-rw-r--r--chromium/components/scheduler/base/DEPS9
-rw-r--r--chromium/components/scheduler/base/cancelable_closure_holder.cc (renamed from chromium/components/scheduler/child/cancelable_closure_holder.cc)8
-rw-r--r--chromium/components/scheduler/base/cancelable_closure_holder.h (renamed from chromium/components/scheduler/child/cancelable_closure_holder.h)6
-rw-r--r--chromium/components/scheduler/base/lazy_now.cc19
-rw-r--r--chromium/components/scheduler/base/lazy_now.h37
-rw-r--r--chromium/components/scheduler/base/nestable_single_thread_task_runner.h (renamed from chromium/components/scheduler/child/nestable_single_thread_task_runner.h)12
-rw-r--r--chromium/components/scheduler/base/nestable_task_runner_for_test.cc46
-rw-r--r--chromium/components/scheduler/base/nestable_task_runner_for_test.h (renamed from chromium/components/scheduler/child/nestable_task_runner_for_test.h)24
-rw-r--r--chromium/components/scheduler/base/pollable_thread_safe_flag.cc (renamed from chromium/components/scheduler/child/pollable_thread_safe_flag.cc)8
-rw-r--r--chromium/components/scheduler/base/pollable_thread_safe_flag.h (renamed from chromium/components/scheduler/child/pollable_thread_safe_flag.h)6
-rw-r--r--chromium/components/scheduler/base/task_queue.cc13
-rw-r--r--chromium/components/scheduler/base/task_queue.h184
-rw-r--r--chromium/components/scheduler/base/task_queue_impl.cc504
-rw-r--r--chromium/components/scheduler/base/task_queue_impl.h212
-rw-r--r--chromium/components/scheduler/base/task_queue_manager.cc464
-rw-r--r--chromium/components/scheduler/base/task_queue_manager.h261
-rw-r--r--chromium/components/scheduler/base/task_queue_manager_perftest.cc (renamed from chromium/components/scheduler/child/task_queue_manager_perftest.cc)77
-rw-r--r--chromium/components/scheduler/base/task_queue_manager_unittest.cc1309
-rw-r--r--chromium/components/scheduler/base/task_queue_selector.cc127
-rw-r--r--chromium/components/scheduler/base/task_queue_selector.h100
-rw-r--r--chromium/components/scheduler/base/task_queue_selector_unittest.cc283
-rw-r--r--chromium/components/scheduler/base/task_queue_sets.cc96
-rw-r--r--chromium/components/scheduler/base/task_queue_sets.h75
-rw-r--r--chromium/components/scheduler/base/task_queue_sets_unittest.cc239
-rw-r--r--chromium/components/scheduler/base/test_always_fail_time_source.cc21
-rw-r--r--chromium/components/scheduler/base/test_always_fail_time_source.h25
-rw-r--r--chromium/components/scheduler/base/test_time_source.cc (renamed from chromium/components/scheduler/child/test_time_source.cc)8
-rw-r--r--chromium/components/scheduler/base/test_time_source.h (renamed from chromium/components/scheduler/child/test_time_source.h)6
-rw-r--r--chromium/components/scheduler/child/DEPS2
-rw-r--r--chromium/components/scheduler/child/child_scheduler.h3
-rw-r--r--chromium/components/scheduler/child/idle_helper.cc170
-rw-r--r--chromium/components/scheduler/child/idle_helper.h21
-rw-r--r--chromium/components/scheduler/child/idle_helper_unittest.cc32
-rw-r--r--chromium/components/scheduler/child/nestable_task_runner_for_test.cc83
-rw-r--r--chromium/components/scheduler/child/null_idle_task_runner.cc31
-rw-r--r--chromium/components/scheduler/child/null_idle_task_runner.h33
-rw-r--r--chromium/components/scheduler/child/null_task_queue.cc41
-rw-r--r--chromium/components/scheduler/child/null_task_queue.h39
-rw-r--r--chromium/components/scheduler/child/null_worker_scheduler.cc55
-rw-r--r--chromium/components/scheduler/child/null_worker_scheduler.h37
-rw-r--r--chromium/components/scheduler/child/prioritizing_task_queue_selector.cc192
-rw-r--r--chromium/components/scheduler/child/prioritizing_task_queue_selector.h108
-rw-r--r--chromium/components/scheduler/child/prioritizing_task_queue_selector_unittest.cc248
-rw-r--r--chromium/components/scheduler/child/scheduler_helper.cc190
-rw-r--r--chromium/components/scheduler/child/scheduler_helper.h86
-rw-r--r--chromium/components/scheduler/child/scheduler_helper_unittest.cc108
-rw-r--r--chromium/components/scheduler/child/scheduler_message_loop_delegate.cc56
-rw-r--r--chromium/components/scheduler/child/scheduler_task_runner_delegate.h37
-rw-r--r--chromium/components/scheduler/child/scheduler_task_runner_delegate_for_test.cc58
-rw-r--r--chromium/components/scheduler/child/scheduler_task_runner_delegate_for_test.h52
-rw-r--r--chromium/components/scheduler/child/scheduler_task_runner_delegate_impl.cc57
-rw-r--r--chromium/components/scheduler/child/scheduler_task_runner_delegate_impl.h (renamed from chromium/components/scheduler/child/scheduler_message_loop_delegate.h)29
-rw-r--r--chromium/components/scheduler/child/scheduler_task_runner_delegate_impl_unittest.cc28
-rw-r--r--chromium/components/scheduler/child/task_queue.h31
-rw-r--r--chromium/components/scheduler/child/task_queue_manager.cc862
-rw-r--r--chromium/components/scheduler/child/task_queue_manager.h265
-rw-r--r--chromium/components/scheduler/child/task_queue_manager_unittest.cc1331
-rw-r--r--chromium/components/scheduler/child/task_queue_selector.h56
-rw-r--r--chromium/components/scheduler/child/web_scheduler_impl.cc42
-rw-r--r--chromium/components/scheduler/child/web_scheduler_impl.h38
-rw-r--r--chromium/components/scheduler/child/web_task_runner_impl.cc39
-rw-r--r--chromium/components/scheduler/child/web_task_runner_impl.h46
-rw-r--r--chromium/components/scheduler/child/webthread_base.cc45
-rw-r--r--chromium/components/scheduler/child/webthread_base.h15
-rw-r--r--chromium/components/scheduler/child/webthread_impl_for_worker_scheduler.cc31
-rw-r--r--chromium/components/scheduler/child/webthread_impl_for_worker_scheduler.h13
-rw-r--r--chromium/components/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc23
-rw-r--r--chromium/components/scheduler/child/worker_scheduler.cc15
-rw-r--r--chromium/components/scheduler/child/worker_scheduler.h4
-rw-r--r--chromium/components/scheduler/child/worker_scheduler_impl.cc9
-rw-r--r--chromium/components/scheduler/child/worker_scheduler_impl.h10
-rw-r--r--chromium/components/scheduler/child/worker_scheduler_impl_unittest.cc17
-rw-r--r--chromium/components/scheduler/common/scheduler_switches.cc15
-rw-r--r--chromium/components/scheduler/common/scheduler_switches.h16
-rw-r--r--chromium/components/scheduler/ppapi/DEPS6
-rw-r--r--chromium/components/scheduler/ppapi/webthread_impl_for_ppapi.cc65
-rw-r--r--chromium/components/scheduler/ppapi/webthread_impl_for_ppapi.h57
-rw-r--r--chromium/components/scheduler/renderer/DEPS3
-rw-r--r--chromium/components/scheduler/renderer/deadline_task_runner.h2
-rw-r--r--chromium/components/scheduler/renderer/null_renderer_scheduler.cc106
-rw-r--r--chromium/components/scheduler/renderer/null_renderer_scheduler.h55
-rw-r--r--chromium/components/scheduler/renderer/renderer_scheduler.cc47
-rw-r--r--chromium/components/scheduler/renderer/renderer_scheduler.h52
-rw-r--r--chromium/components/scheduler/renderer/renderer_scheduler_impl.cc724
-rw-r--r--chromium/components/scheduler/renderer/renderer_scheduler_impl.h165
-rw-r--r--chromium/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc637
-rw-r--r--chromium/components/scheduler/renderer/renderer_web_scheduler_impl.cc20
-rw-r--r--chromium/components/scheduler/renderer/renderer_web_scheduler_impl.h8
-rw-r--r--chromium/components/scheduler/renderer/task_cost_estimator.cc47
-rw-r--r--chromium/components/scheduler/renderer/task_cost_estimator.h51
-rw-r--r--chromium/components/scheduler/renderer/task_cost_estimator_unittest.cc75
-rw-r--r--chromium/components/scheduler/renderer/user_model.cc110
-rw-r--r--chromium/components/scheduler/renderer/user_model.h69
-rw-r--r--chromium/components/scheduler/renderer/user_model_unittest.cc298
-rw-r--r--chromium/components/scheduler/renderer/web_frame_host_scheduler_impl.cc39
-rw-r--r--chromium/components/scheduler/renderer/web_frame_host_scheduler_impl.h46
-rw-r--r--chromium/components/scheduler/renderer/web_frame_scheduler_impl.cc60
-rw-r--r--chromium/components/scheduler/renderer/web_frame_scheduler_impl.h54
-rw-r--r--chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc11
-rw-r--r--chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h7
-rw-r--r--chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc44
-rw-r--r--chromium/components/scheduler/scheduler.gyp12
-rw-r--r--chromium/components/scheduler/scheduler.gypi57
-rw-r--r--chromium/components/search.gypi5
-rw-r--r--chromium/components/search_engines.gypi2
-rw-r--r--chromium/components/security_interstitials.gypi28
-rw-r--r--chromium/components/security_interstitials/DEPS6
-rw-r--r--chromium/components/security_interstitials/OWNERS6
-rw-r--r--chromium/components/security_interstitials/README4
-rw-r--r--chromium/components/security_interstitials/core/BUILD.gn19
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/captive_portal.js5
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/extended_reporting.js41
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/1x/brokenssl_red.pngbin0 -> 1563 bytes
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/1x/captive_portal_page_icon.pngbin0 -> 1281 bytes
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/1x/clock.pngbin0 -> 1500 bytes
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/1x/stop_sign.pngbin0 -> 1621 bytes
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/2x/brokenssl_red.pngbin0 -> 2970 bytes
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/2x/captive_portal_page_icon.pngbin0 -> 2690 bytes
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/2x/clock.pngbin0 -> 3320 bytes
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/2x/stop_sign.pngbin0 -> 3103 bytes
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_ui.html55
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_v2.css635
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_v2.html47
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_v2.js192
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js50
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/ssl.js18
-rw-r--r--chromium/components/security_interstitials/core/metrics_helper.cc152
-rw-r--r--chromium/components/security_interstitials/core/metrics_helper.h125
-rw-r--r--chromium/components/security_interstitials_strings.grdp52
-rw-r--r--chromium/components/sessions.gypi79
-rw-r--r--chromium/components/signin.gypi91
-rw-r--r--chromium/components/ssl_errors.gypi27
-rw-r--r--chromium/components/ssl_errors_strings.grdp159
-rw-r--r--chromium/components/strings/BUILD.gn173
-rw-r--r--chromium/components/strings/components_chromium_strings_am.xtb17
-rw-r--r--chromium/components/strings/components_chromium_strings_ar.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_bg.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_bn.xtb17
-rw-r--r--chromium/components/strings/components_chromium_strings_ca.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_cs.xtb8
-rw-r--r--chromium/components/strings/components_chromium_strings_da.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_de.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_el.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_en-GB.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_es-419.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_es.xtb15
-rw-r--r--chromium/components/strings/components_chromium_strings_et.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_fa.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_fi.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_fil.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_fr.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_gu.xtb17
-rw-r--r--chromium/components/strings/components_chromium_strings_hi.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_hr.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_hu.xtb17
-rw-r--r--chromium/components/strings/components_chromium_strings_id.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_it.xtb10
-rw-r--r--chromium/components/strings/components_chromium_strings_iw.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_ja.xtb17
-rw-r--r--chromium/components/strings/components_chromium_strings_kn.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_ko.xtb17
-rw-r--r--chromium/components/strings/components_chromium_strings_lt.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_lv.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_ml.xtb16
-rw-r--r--chromium/components/strings/components_chromium_strings_mr.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_ms.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_nl.xtb15
-rw-r--r--chromium/components/strings/components_chromium_strings_no.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_pl.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_pt-BR.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_pt-PT.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_ro.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_ru.xtb8
-rw-r--r--chromium/components/strings/components_chromium_strings_sk.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_sl.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_sr.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_sv.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_sw.xtb15
-rw-r--r--chromium/components/strings/components_chromium_strings_ta.xtb16
-rw-r--r--chromium/components/strings/components_chromium_strings_te.xtb17
-rw-r--r--chromium/components/strings/components_chromium_strings_th.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_tr.xtb16
-rw-r--r--chromium/components/strings/components_chromium_strings_uk.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_vi.xtb18
-rw-r--r--chromium/components/strings/components_chromium_strings_zh-CN.xtb9
-rw-r--r--chromium/components/strings/components_chromium_strings_zh-TW.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_am.xtb17
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ar.xtb21
-rw-r--r--chromium/components/strings/components_google_chrome_strings_bg.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_bn.xtb17
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ca.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_cs.xtb8
-rw-r--r--chromium/components/strings/components_google_chrome_strings_da.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_de.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_el.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_en-GB.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_es-419.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_es.xtb15
-rw-r--r--chromium/components/strings/components_google_chrome_strings_et.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_fa.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_fi.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_fil.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_fr.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_gu.xtb17
-rw-r--r--chromium/components/strings/components_google_chrome_strings_hi.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_hr.xtb17
-rw-r--r--chromium/components/strings/components_google_chrome_strings_hu.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_id.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_it.xtb10
-rw-r--r--chromium/components/strings/components_google_chrome_strings_iw.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ja.xtb17
-rw-r--r--chromium/components/strings/components_google_chrome_strings_kn.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ko.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_lt.xtb19
-rw-r--r--chromium/components/strings/components_google_chrome_strings_lv.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ml.xtb16
-rw-r--r--chromium/components/strings/components_google_chrome_strings_mr.xtb17
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ms.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_nl.xtb15
-rw-r--r--chromium/components/strings/components_google_chrome_strings_no.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_pl.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_pt-BR.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_pt-PT.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ro.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ru.xtb8
-rw-r--r--chromium/components/strings/components_google_chrome_strings_sk.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_sl.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_sr.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_sv.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_sw.xtb17
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ta.xtb16
-rw-r--r--chromium/components/strings/components_google_chrome_strings_te.xtb17
-rw-r--r--chromium/components/strings/components_google_chrome_strings_th.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_tr.xtb16
-rw-r--r--chromium/components/strings/components_google_chrome_strings_uk.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_vi.xtb18
-rw-r--r--chromium/components/strings/components_google_chrome_strings_zh-CN.xtb9
-rw-r--r--chromium/components/strings/components_google_chrome_strings_zh-TW.xtb18
-rw-r--r--chromium/components/strings/components_strings_am.xtb166
-rw-r--r--chromium/components/strings/components_strings_ar.xtb166
-rw-r--r--chromium/components/strings/components_strings_bg.xtb166
-rw-r--r--chromium/components/strings/components_strings_bn.xtb166
-rw-r--r--chromium/components/strings/components_strings_ca.xtb166
-rw-r--r--chromium/components/strings/components_strings_cs.xtb166
-rw-r--r--chromium/components/strings/components_strings_da.xtb166
-rw-r--r--chromium/components/strings/components_strings_de.xtb166
-rw-r--r--chromium/components/strings/components_strings_el.xtb166
-rw-r--r--chromium/components/strings/components_strings_en-GB.xtb167
-rw-r--r--chromium/components/strings/components_strings_es-419.xtb168
-rw-r--r--chromium/components/strings/components_strings_es.xtb166
-rw-r--r--chromium/components/strings/components_strings_et.xtb166
-rw-r--r--chromium/components/strings/components_strings_fa.xtb168
-rw-r--r--chromium/components/strings/components_strings_fi.xtb166
-rw-r--r--chromium/components/strings/components_strings_fil.xtb166
-rw-r--r--chromium/components/strings/components_strings_fr.xtb166
-rw-r--r--chromium/components/strings/components_strings_gu.xtb166
-rw-r--r--chromium/components/strings/components_strings_hi.xtb166
-rw-r--r--chromium/components/strings/components_strings_hr.xtb166
-rw-r--r--chromium/components/strings/components_strings_hu.xtb166
-rw-r--r--chromium/components/strings/components_strings_id.xtb166
-rw-r--r--chromium/components/strings/components_strings_it.xtb166
-rw-r--r--chromium/components/strings/components_strings_iw.xtb170
-rw-r--r--chromium/components/strings/components_strings_ja.xtb166
-rw-r--r--chromium/components/strings/components_strings_kn.xtb166
-rw-r--r--chromium/components/strings/components_strings_ko.xtb166
-rw-r--r--chromium/components/strings/components_strings_lt.xtb166
-rw-r--r--chromium/components/strings/components_strings_lv.xtb166
-rw-r--r--chromium/components/strings/components_strings_ml.xtb166
-rw-r--r--chromium/components/strings/components_strings_mr.xtb168
-rw-r--r--chromium/components/strings/components_strings_ms.xtb168
-rw-r--r--chromium/components/strings/components_strings_nl.xtb166
-rw-r--r--chromium/components/strings/components_strings_no.xtb166
-rw-r--r--chromium/components/strings/components_strings_pl.xtb166
-rw-r--r--chromium/components/strings/components_strings_pt-BR.xtb166
-rw-r--r--chromium/components/strings/components_strings_pt-PT.xtb167
-rw-r--r--chromium/components/strings/components_strings_ro.xtb166
-rw-r--r--chromium/components/strings/components_strings_ru.xtb168
-rw-r--r--chromium/components/strings/components_strings_sk.xtb167
-rw-r--r--chromium/components/strings/components_strings_sl.xtb167
-rw-r--r--chromium/components/strings/components_strings_sr.xtb166
-rw-r--r--chromium/components/strings/components_strings_sv.xtb166
-rw-r--r--chromium/components/strings/components_strings_sw.xtb162
-rw-r--r--chromium/components/strings/components_strings_ta.xtb166
-rw-r--r--chromium/components/strings/components_strings_te.xtb166
-rw-r--r--chromium/components/strings/components_strings_th.xtb166
-rw-r--r--chromium/components/strings/components_strings_tr.xtb166
-rw-r--r--chromium/components/strings/components_strings_uk.xtb168
-rw-r--r--chromium/components/strings/components_strings_vi.xtb166
-rw-r--r--chromium/components/strings/components_strings_zh-CN.xtb166
-rw-r--r--chromium/components/strings/components_strings_zh-TW.xtb166
-rw-r--r--chromium/components/suggestions.gypi1
-rw-r--r--chromium/components/sync_driver.gypi81
-rw-r--r--chromium/components/syncable_prefs.gypi61
-rw-r--r--chromium/components/test_runner/test_runner.gyp4
-rw-r--r--chromium/components/toolbar.gypi25
-rw-r--r--chromium/components/tracing.gyp12
-rw-r--r--chromium/components/tracing/BUILD.gn30
-rw-r--r--chromium/components/tracing/DEPS1
-rw-r--r--chromium/components/tracing/OWNERS1
-rw-r--r--chromium/components/tracing/child_memory_dump_manager_delegate_impl.cc64
-rw-r--r--chromium/components/tracing/child_memory_dump_manager_delegate_impl.h24
-rw-r--r--chromium/components/tracing/child_trace_message_filter.cc85
-rw-r--r--chromium/components/tracing/child_trace_message_filter.h16
-rw-r--r--chromium/components/tracing/startup_tracing.cc66
-rw-r--r--chromium/components/tracing/startup_tracing.h18
-rw-r--r--chromium/components/tracing/trace_config_file.cc140
-rw-r--r--chromium/components/tracing/trace_config_file.h96
-rw-r--r--chromium/components/tracing/trace_config_file_unittest.cc220
-rw-r--r--chromium/components/tracing/tracing_export.h29
-rw-r--r--chromium/components/tracing/tracing_messages.h23
-rw-r--r--chromium/components/tracing/tracing_switches.cc52
-rw-r--r--chromium/components/tracing/tracing_switches.h22
-rw-r--r--chromium/components/tracing_nacl.gyp7
-rw-r--r--chromium/components/translate.gypi11
-rw-r--r--chromium/components/ui_zoom.gypi1
-rw-r--r--chromium/components/upload_list.gypi25
-rw-r--r--chromium/components/url_formatter/BUILD.gn50
-rw-r--r--chromium/components/url_formatter/DEPS11
-rw-r--r--chromium/components/url_formatter/OWNERS9
-rw-r--r--chromium/components/url_formatter/elide_url.cc370
-rw-r--r--chromium/components/url_formatter/elide_url.h86
-rw-r--r--chromium/components/url_formatter/elide_url_unittest.cc366
-rw-r--r--chromium/components/url_formatter/url_fixer.cc673
-rw-r--r--chromium/components/url_formatter/url_fixer.h87
-rw-r--r--chromium/components/url_formatter/url_fixer_unittest.cc537
-rw-r--r--chromium/components/url_formatter/url_formatter.cc807
-rw-r--r--chromium/components/url_formatter/url_formatter.gyp39
-rw-r--r--chromium/components/url_formatter/url_formatter.h155
-rw-r--r--chromium/components/url_formatter/url_formatter_unittest.cc978
-rw-r--r--chromium/components/user_manager.gypi1
-rw-r--r--chromium/components/user_prefs.gypi72
-rw-r--r--chromium/components/user_prefs/BUILD.gn18
-rw-r--r--chromium/components/user_prefs/DEPS6
-rw-r--r--chromium/components/user_prefs/OWNERS4
-rw-r--r--chromium/components/user_prefs/README8
-rw-r--r--chromium/components/user_prefs/tracked/BUILD.gn94
-rw-r--r--chromium/components/user_prefs/tracked/DEPS4
-rw-r--r--chromium/components/user_prefs/tracked/OWNERS2
-rw-r--r--chromium/components/user_prefs/tracked/device_id.h23
-rw-r--r--chromium/components/user_prefs/tracked/device_id_mac.cc32
-rw-r--r--chromium/components/user_prefs/tracked/device_id_stub.cc11
-rw-r--r--chromium/components/user_prefs/tracked/device_id_unittest.cc35
-rw-r--r--chromium/components/user_prefs/tracked/device_id_win.cc71
-rw-r--r--chromium/components/user_prefs/tracked/dictionary_hash_store_contents.cc94
-rw-r--r--chromium/components/user_prefs/tracked/dictionary_hash_store_contents.h48
-rw-r--r--chromium/components/user_prefs/tracked/hash_store_contents.h63
-rw-r--r--chromium/components/user_prefs/tracked/interceptable_pref_filter.cc39
-rw-r--r--chromium/components/user_prefs/tracked/interceptable_pref_filter.h64
-rw-r--r--chromium/components/user_prefs/tracked/mock_validation_delegate.cc58
-rw-r--r--chromium/components/user_prefs/tracked/mock_validation_delegate.h74
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_calculator.cc125
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_calculator.h52
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_calculator_unittest.cc202
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_filter.cc230
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_filter.h141
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_filter_unittest.cc1039
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_store.h28
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_store_impl.cc308
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_store_impl.h67
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_store_impl_unittest.cc474
-rw-r--r--chromium/components/user_prefs/tracked/pref_hash_store_transaction.h94
-rw-r--r--chromium/components/user_prefs/tracked/pref_names.cc13
-rw-r--r--chromium/components/user_prefs/tracked/pref_names.h14
-rw-r--r--chromium/components/user_prefs/tracked/pref_service_hash_store_contents.cc146
-rw-r--r--chromium/components/user_prefs/tracked/pref_service_hash_store_contents.h72
-rw-r--r--chromium/components/user_prefs/tracked/pref_service_hash_store_contents_unittest.cc152
-rw-r--r--chromium/components/user_prefs/tracked/segregated_pref_store.cc173
-rw-r--r--chromium/components/user_prefs/tracked/segregated_pref_store.h110
-rw-r--r--chromium/components/user_prefs/tracked/segregated_pref_store_unittest.cc273
-rw-r--r--chromium/components/user_prefs/tracked/tracked_atomic_preference.cc65
-rw-r--r--chromium/components/user_prefs/tracked/tracked_atomic_preference.h44
-rw-r--r--chromium/components/user_prefs/tracked/tracked_preference.h36
-rw-r--r--chromium/components/user_prefs/tracked/tracked_preference_helper.cc118
-rw-r--r--chromium/components/user_prefs/tracked/tracked_preference_helper.h67
-rw-r--r--chromium/components/user_prefs/tracked/tracked_preference_validation_delegate.h44
-rw-r--r--chromium/components/user_prefs/tracked/tracked_preferences_migration.cc370
-rw-r--r--chromium/components/user_prefs/tracked/tracked_preferences_migration.h48
-rw-r--r--chromium/components/user_prefs/tracked/tracked_preferences_migration_unittest.cc905
-rw-r--r--chromium/components/user_prefs/tracked/tracked_split_preference.cc92
-rw-r--r--chromium/components/user_prefs/tracked/tracked_split_preference.h47
-rw-r--r--chromium/components/user_prefs/user_prefs.cc46
-rw-r--r--chromium/components/user_prefs/user_prefs.h42
-rw-r--r--chromium/components/user_prefs/user_prefs_export.h29
-rw-r--r--chromium/components/variations.gypi57
-rw-r--r--chromium/components/version_info.grdp8
-rw-r--r--chromium/components/version_info.gypi116
-rw-r--r--chromium/components/visitedlink/browser/BUILD.gn3
-rw-r--r--chromium/components/visitedlink/browser/visitedlink_event_listener.h2
-rw-r--r--chromium/components/visitedlink/common/BUILD.gn3
-rw-r--r--chromium/components/visitedlink/renderer/BUILD.gn27
-rw-r--r--chromium/components/web_cache/browser/BUILD.gn17
-rw-r--r--chromium/components/web_cache/browser/web_cache_manager.cc2
-rw-r--r--chromium/components/web_cache/browser/web_cache_manager.h5
-rw-r--r--chromium/components/web_cache/common/BUILD.gn3
-rw-r--r--chromium/components/web_cache/renderer/BUILD.gn4
-rw-r--r--chromium/components/web_modal.gypi2
-rw-r--r--chromium/components/web_resource.gypi17
-rw-r--r--chromium/components/webcrypto/BUILD.gn112
-rw-r--r--chromium/components/webcrypto/DEPS1
-rw-r--r--chromium/components/webcrypto/algorithm_dispatch.cc26
-rw-r--r--chromium/components/webcrypto/algorithm_implementation.cc4
-rw-r--r--chromium/components/webcrypto/algorithm_implementation.h12
-rw-r--r--chromium/components/webcrypto/algorithm_implementations.h35
-rw-r--r--chromium/components/webcrypto/algorithm_registry.cc31
-rw-r--r--chromium/components/webcrypto/algorithms/aes.cc (renamed from chromium/components/webcrypto/openssl/aes_algorithm_openssl.cc)113
-rw-r--r--chromium/components/webcrypto/algorithms/aes.h (renamed from chromium/components/webcrypto/openssl/aes_algorithm_openssl.h)10
-rw-r--r--chromium/components/webcrypto/algorithms/aes_cbc.cc (renamed from chromium/components/webcrypto/openssl/aes_cbc_openssl.cc)16
-rw-r--r--chromium/components/webcrypto/algorithms/aes_cbc_unittest.cc568
-rw-r--r--chromium/components/webcrypto/algorithms/aes_ctr.cc (renamed from chromium/components/webcrypto/openssl/aes_ctr_openssl.cc)16
-rw-r--r--chromium/components/webcrypto/algorithms/aes_ctr_unittest.cc170
-rw-r--r--chromium/components/webcrypto/algorithms/aes_gcm.cc (renamed from chromium/components/webcrypto/openssl/aes_gcm_openssl.cc)32
-rw-r--r--chromium/components/webcrypto/algorithms/aes_gcm_unittest.cc222
-rw-r--r--chromium/components/webcrypto/algorithms/aes_kw.cc (renamed from chromium/components/webcrypto/openssl/aes_kw_openssl.cc)20
-rw-r--r--chromium/components/webcrypto/algorithms/aes_kw_unittest.cc538
-rw-r--r--chromium/components/webcrypto/algorithms/asymmetric_key_util.cc (renamed from chromium/components/webcrypto/openssl/util_openssl.cc)183
-rw-r--r--chromium/components/webcrypto/algorithms/asymmetric_key_util.h83
-rw-r--r--chromium/components/webcrypto/algorithms/ec.cc (renamed from chromium/components/webcrypto/openssl/ec_algorithm_openssl.cc)50
-rw-r--r--chromium/components/webcrypto/algorithms/ec.h (renamed from chromium/components/webcrypto/openssl/ec_algorithm_openssl.h)10
-rw-r--r--chromium/components/webcrypto/algorithms/ecdh.cc (renamed from chromium/components/webcrypto/openssl/ecdh_openssl.cc)15
-rw-r--r--chromium/components/webcrypto/algorithms/ecdh_unittest.cc331
-rw-r--r--chromium/components/webcrypto/algorithms/ecdsa.cc (renamed from chromium/components/webcrypto/openssl/ecdsa_openssl.cc)15
-rw-r--r--chromium/components/webcrypto/algorithms/ecdsa_unittest.cc349
-rw-r--r--chromium/components/webcrypto/algorithms/hkdf.cc (renamed from chromium/components/webcrypto/openssl/hkdf_openssl.cc)24
-rw-r--r--chromium/components/webcrypto/algorithms/hmac.cc (renamed from chromium/components/webcrypto/openssl/hmac_openssl.cc)122
-rw-r--r--chromium/components/webcrypto/algorithms/hmac_unittest.cc602
-rw-r--r--chromium/components/webcrypto/algorithms/pbkdf2.cc (renamed from chromium/components/webcrypto/openssl/pbkdf2_openssl.cc)25
-rw-r--r--chromium/components/webcrypto/algorithms/rsa.cc (renamed from chromium/components/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc)222
-rw-r--r--chromium/components/webcrypto/algorithms/rsa.h (renamed from chromium/components/webcrypto/openssl/rsa_hashed_algorithm_openssl.h)10
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_oaep.cc (renamed from chromium/components/webcrypto/openssl/rsa_oaep_openssl.cc)15
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_oaep_unittest.cc504
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_pss.cc (renamed from chromium/components/webcrypto/openssl/rsa_pss_openssl.cc)8
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_pss_unittest.cc230
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_sign.cc (renamed from chromium/components/webcrypto/openssl/rsa_sign_openssl.cc)10
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_sign.h (renamed from chromium/components/webcrypto/openssl/rsa_sign_openssl.h)6
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_ssa.cc (renamed from chromium/components/webcrypto/openssl/rsa_ssa_openssl.cc)8
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_ssa_unittest.cc1020
-rw-r--r--chromium/components/webcrypto/algorithms/secret_key_util.cc91
-rw-r--r--chromium/components/webcrypto/algorithms/secret_key_util.h73
-rw-r--r--chromium/components/webcrypto/algorithms/sha.cc (renamed from chromium/components/webcrypto/openssl/sha_openssl.cc)19
-rw-r--r--chromium/components/webcrypto/algorithms/sha_unittest.cc84
-rw-r--r--chromium/components/webcrypto/algorithms/test_helpers.cc684
-rw-r--r--chromium/components/webcrypto/algorithms/test_helpers.h236
-rw-r--r--chromium/components/webcrypto/algorithms/util.cc127
-rw-r--r--chromium/components/webcrypto/algorithms/util.h96
-rw-r--r--chromium/components/webcrypto/blink_key_handle.cc111
-rw-r--r--chromium/components/webcrypto/blink_key_handle.h61
-rw-r--r--chromium/components/webcrypto/jwk.cc214
-rw-r--r--chromium/components/webcrypto/jwk.h100
-rw-r--r--chromium/components/webcrypto/nss/aes_algorithm_nss.cc141
-rw-r--r--chromium/components/webcrypto/nss/aes_algorithm_nss.h85
-rw-r--r--chromium/components/webcrypto/nss/aes_cbc_nss.cc120
-rw-r--r--chromium/components/webcrypto/nss/aes_gcm_nss.cc182
-rw-r--r--chromium/components/webcrypto/nss/aes_kw_nss.cc186
-rw-r--r--chromium/components/webcrypto/nss/hmac_nss.cc261
-rw-r--r--chromium/components/webcrypto/nss/key_nss.cc85
-rw-r--r--chromium/components/webcrypto/nss/key_nss.h105
-rw-r--r--chromium/components/webcrypto/nss/rsa_hashed_algorithm_nss.cc858
-rw-r--r--chromium/components/webcrypto/nss/rsa_hashed_algorithm_nss.h99
-rw-r--r--chromium/components/webcrypto/nss/rsa_oaep_nss.cc227
-rw-r--r--chromium/components/webcrypto/nss/rsa_ssa_nss.cc133
-rw-r--r--chromium/components/webcrypto/nss/sha_nss.cc156
-rw-r--r--chromium/components/webcrypto/nss/sym_key_nss.cc76
-rw-r--r--chromium/components/webcrypto/nss/sym_key_nss.h34
-rw-r--r--chromium/components/webcrypto/nss/util_nss.cc113
-rw-r--r--chromium/components/webcrypto/nss/util_nss.h112
-rw-r--r--chromium/components/webcrypto/openssl/key_openssl.cc62
-rw-r--r--chromium/components/webcrypto/openssl/key_openssl.h79
-rw-r--r--chromium/components/webcrypto/openssl/util_openssl.h101
-rw-r--r--chromium/components/webcrypto/platform_crypto.h40
-rw-r--r--chromium/components/webcrypto/status.h2
-rw-r--r--chromium/components/webcrypto/status_unittest.cc74
-rw-r--r--chromium/components/webcrypto/webcrypto.gyp158
-rw-r--r--chromium/components/webcrypto/webcrypto_impl.cc3
-rw-r--r--chromium/components/webcrypto/webcrypto_impl.h155
-rw-r--r--chromium/components/webcrypto/webcrypto_util.cc328
-rw-r--r--chromium/components/webcrypto/webcrypto_util.h133
-rw-r--r--chromium/components/webusb.gypi25
676 files changed, 43888 insertions, 13419 deletions
diff --git a/chromium/components/url_fixer.gypi b/chromium/components/about_handler.gypi
index 917e9d77d74..fce5b8c8b55 100644
--- a/chromium/components/url_fixer.gypi
+++ b/chromium/components/about_handler.gypi
@@ -1,27 +1,27 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
+# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'targets': [
{
- # GN version: //components/url_fixer
- 'target_name': 'url_fixer',
+ # GN version: //components/about_handler
+ 'target_name': 'about_handler',
'type': 'static_library',
- 'include_dirs': [
- '..',
- ],
'dependencies': [
'../base/base.gyp:base',
'../net/net.gyp:net',
],
+ 'include_dirs': [
+ '..',
+ ],
'sources': [
# Note: sources list duplicated in GN build.
- 'url_fixer/url_fixer.cc',
- 'url_fixer/url_fixer.h',
+ 'about_handler/about_protocol_handler.cc',
+ 'about_handler/about_protocol_handler.h',
+ 'about_handler/url_request_about_job.cc',
+ 'about_handler/url_request_about_job.h',
],
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- 'msvs_disabled_warnings': [4267, ],
},
],
}
diff --git a/chromium/components/app_modal.gypi b/chromium/components/app_modal.gypi
index 8f85d8cba3e..045b1ec219a 100644
--- a/chromium/components/app_modal.gypi
+++ b/chromium/components/app_modal.gypi
@@ -7,10 +7,11 @@
'target_name': 'app_modal',
'type': 'static_library',
'dependencies': [
- '../content/content.gyp:content_browser',
- '../content/content.gyp:content_common',
+ '../content/content.gyp:content_browser',
+ '../content/content.gyp:content_common',
'../skia/skia.gyp:skia',
'components_strings.gyp:components_strings',
+ 'url_formatter/url_formatter.gyp:url_formatter',
],
'include_dirs': [
'..',
diff --git a/chromium/components/audio_modem.gypi b/chromium/components/audio_modem.gypi
index 7d2219bc5e2..58d892883e2 100644
--- a/chromium/components/audio_modem.gypi
+++ b/chromium/components/audio_modem.gypi
@@ -12,6 +12,7 @@
'../content/content.gyp:content_common',
'../media/media.gyp:media',
'../media/media.gyp:shared_memory_support',
+ '../third_party/webrtc/common_audio/common_audio.gyp:common_audio',
],
'include_dirs': [
'..',
diff --git a/chromium/components/autofill.gypi b/chromium/components/autofill.gypi
index bfac495fbf0..456451e4d06 100644
--- a/chromium/components/autofill.gypi
+++ b/chromium/components/autofill.gypi
@@ -31,6 +31,8 @@
'autofill/core/common/autofill_regexes.h',
'autofill/core/common/autofill_switches.cc',
'autofill/core/common/autofill_switches.h',
+ 'autofill/core/common/autofill_util.cc',
+ 'autofill/core/common/autofill_util.h',
'autofill/core/common/form_data.cc',
'autofill/core/common/form_data.h',
'autofill/core/common/form_data_predictions.cc',
@@ -81,10 +83,12 @@
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_geometry',
+ '../ui/gfx/gfx.gyp:gfx_vector_icons',
'../url/url.gyp:url_lib',
'autofill_core_common',
'components_resources.gyp:components_resources',
'components_strings.gyp:components_strings',
+ 'data_use_measurement_core',
'infobars_core',
'keyed_service_core',
'os_crypt',
@@ -170,7 +174,6 @@
'autofill/core/browser/password_generator.h',
'autofill/core/browser/personal_data_manager.cc',
'autofill/core/browser/personal_data_manager.h',
- 'autofill/core/browser/personal_data_manager_mac.mm',
'autofill/core/browser/personal_data_manager_observer.h',
'autofill/core/browser/phone_field.cc',
'autofill/core/browser/phone_field.h',
@@ -310,8 +313,6 @@
'../testing/gmock.gyp:gmock',
],
'sources': [
- 'autofill/content/browser/wallet/mock_wallet_client.cc',
- 'autofill/content/browser/wallet/mock_wallet_client.h',
'autofill/content/browser/wallet/wallet_test_util.cc',
'autofill/content/browser/wallet/wallet_test_util.h',
'autofill/content/renderer/test_password_autofill_agent.cc',
@@ -365,27 +366,12 @@
'autofill/content/browser/request_autocomplete_manager.h',
'autofill/content/browser/risk/fingerprint.cc',
'autofill/content/browser/risk/fingerprint.h',
- 'autofill/content/browser/wallet/form_field_error.cc',
- 'autofill/content/browser/wallet/form_field_error.h',
'autofill/content/browser/wallet/full_wallet.cc',
'autofill/content/browser/wallet/full_wallet.h',
- 'autofill/content/browser/wallet/gaia_account.cc',
- 'autofill/content/browser/wallet/gaia_account.h',
- 'autofill/content/browser/wallet/instrument.cc',
- 'autofill/content/browser/wallet/instrument.h',
- 'autofill/content/browser/wallet/required_action.cc',
- 'autofill/content/browser/wallet/required_action.h',
'autofill/content/browser/wallet/wallet_address.cc',
'autofill/content/browser/wallet/wallet_address.h',
- 'autofill/content/browser/wallet/wallet_client.cc',
- 'autofill/content/browser/wallet/wallet_client.h',
- 'autofill/content/browser/wallet/wallet_client_delegate.h',
- 'autofill/content/browser/wallet/wallet_items.cc',
- 'autofill/content/browser/wallet/wallet_items.h',
'autofill/content/browser/wallet/wallet_service_url.cc',
'autofill/content/browser/wallet/wallet_service_url.h',
- 'autofill/content/browser/wallet/wallet_signin_helper.cc',
- 'autofill/content/browser/wallet/wallet_signin_helper.h',
],
# TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
@@ -469,6 +455,8 @@
'autofill/ios/browser/js_autofill_manager.mm',
'autofill/ios/browser/js_suggestion_manager.h',
'autofill/ios/browser/js_suggestion_manager.mm',
+ 'autofill/ios/browser/keyboard_accessory_metrics_logger.h',
+ 'autofill/ios/browser/keyboard_accessory_metrics_logger.mm',
'autofill/ios/browser/personal_data_manager_observer_bridge.h',
'autofill/ios/browser/personal_data_manager_observer_bridge.mm',
],
diff --git a/chromium/components/autofill_strings.grdp b/chromium/components/autofill_strings.grdp
index ccd659709d9..9f36e10c9a3 100644
--- a/chromium/components/autofill_strings.grdp
+++ b/chromium/components/autofill_strings.grdp
@@ -1,9 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<grit-part>
- <message name="IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM" desc="The entry in the suggestions dropdown that clears an auto-filled form.">
- Clear form
- </message>
+ <if expr="not is_ios">
+ <message name="IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM" desc="The entry in the suggestions dropdown that clears an auto-filled form.">
+ Clear form
+ </message>
+ </if>
+ <if expr="is_ios">
+ <message name="IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM" desc="iOS: The entry in the suggestions keyboard accessory that clears an auto-filled form.">
+ CLEAR FORM
+ </message>
+ </if>
<message name="IDS_AUTOFILL_WARNING_FORM_DISABLED" desc="Warning text to show when autofill is disabled by the website for a given form.">
This webpage has disabled automatic filling for this form.
</message>
@@ -96,12 +103,13 @@
Country
</message>
- <message name="IDS_AUTOFILL_SHOW_PREDICTIONS_TITLE" desc="The title for form elements when annotated with Autofill predictions.">
- heuristic type: <ph name="HEURISTIC_TYPE">$1<ex>NAME_FIRST</ex></ph>
+ <message translateable="false" name="IDS_AUTOFILL_SHOW_PREDICTIONS_TITLE" desc="The title for form elements when annotated with Autofill predictions.">
+ overall type: <ph name="OVERALL_TYPE">$1<ex>NAME_FIRST</ex></ph>
server type: <ph name="SERVER_TYPE">$2<ex>NAME_FIRST</ex></ph>
- field signature: <ph name="FIELD_SIGNATURE">$3<ex>12345678</ex></ph>
- form signature: <ph name="FORM_SIGNATURE">$4<ex>1234567812345678</ex></ph>
- experiment id: "<ph name="EXPERIMENT_ID">$5<ex>ar1</ex></ph>"
+ heuristic type: <ph name="HEURISTIC_TYPE">$3<ex>NAME_FIRST</ex></ph>
+ field signature: <ph name="FIELD_SIGNATURE">$4<ex>12345678</ex></ph>
+ form signature: <ph name="FORM_SIGNATURE">$5<ex>1234567812345678</ex></ph>
+ experiment id: "<ph name="EXPERIMENT_ID">$6<ex>ar1</ex></ph>"
</message>
<!-- Autofill dialog: legal documents -->
@@ -119,6 +127,9 @@
Chromium Autofill settings...
</message>
</if>
+ <message name="IDS_AUTOFILL_OPTIONS_CONTENT_DESCRIPTION" desc="The text verbalised by a screen reader for the button that directs the user to the Autofill settings UI. This string is not displayed.">
+ settings
+ </message>
<message name="IDS_AUTOFILL_CREDIT_CARD_NOT_SUPPORTED_BY_WALLET" desc="Message displayed to user when user entered a credit card number that is not supported by Google Payments.">
This type of card is not supported by Google Payments. Please select a different card.
diff --git a/chromium/components/bookmarks.gypi b/chromium/components/bookmarks.gypi
index eabb68adaa3..00b45b711fc 100644
--- a/chromium/components/bookmarks.gypi
+++ b/chromium/components/bookmarks.gypi
@@ -27,6 +27,7 @@
'pref_registry',
'query_parser',
'startup_metric_utils',
+ 'url_formatter/url_formatter.gyp:url_formatter',
],
'sources': [
'bookmarks/browser/base_bookmark_model_observer.cc',
@@ -112,8 +113,13 @@
'dependencies': [
'bookmarks_browser',
'components_strings.gyp:components_strings',
+ 'keyed_service_core',
],
'sources': [
+ 'bookmarks/managed/managed_bookmark_service.cc',
+ 'bookmarks/managed/managed_bookmark_service.h',
+ 'bookmarks/managed/managed_bookmark_util.cc',
+ 'bookmarks/managed/managed_bookmark_util.h',
'bookmarks/managed/managed_bookmarks_tracker.cc',
'bookmarks/managed/managed_bookmarks_tracker.h',
],
diff --git a/chromium/components/bubble.gypi b/chromium/components/bubble.gypi
new file mode 100644
index 00000000000..76cf9370a60
--- /dev/null
+++ b/chromium/components/bubble.gypi
@@ -0,0 +1,43 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/bubble
+ 'target_name': 'bubble',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'bubble/bubble_close_reason.h',
+ 'bubble/bubble_controller.cc',
+ 'bubble/bubble_controller.h',
+ 'bubble/bubble_delegate.cc',
+ 'bubble/bubble_delegate.h',
+ 'bubble/bubble_manager.cc',
+ 'bubble/bubble_manager.h',
+ 'bubble/bubble_reference.h',
+ 'bubble/bubble_ui.h',
+ ],
+ },
+ {
+ 'target_name': 'bubble_test_support',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ '../testing/gmock.gyp:gmock',
+ 'bubble',
+ ],
+ 'sources': [
+ 'bubble/bubble_manager_mocks.cc',
+ 'bubble/bubble_manager_mocks.h',
+ ],
+ },
+ ],
+}
diff --git a/chromium/components/certificate_reporting.gypi b/chromium/components/certificate_reporting.gypi
new file mode 100644
index 00000000000..87f9f50fdd6
--- /dev/null
+++ b/chromium/components/certificate_reporting.gypi
@@ -0,0 +1,57 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/certificate_reporting
+ 'target_name': 'certificate_reporting',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../crypto/crypto.gyp:crypto',
+ '../net/net.gyp:net',
+ '../url/url.gyp:url_lib',
+ 'cert_logger_proto',
+ 'encrypted_cert_logger_proto',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ "certificate_reporting/error_report.cc",
+ "certificate_reporting/error_report.h",
+ "certificate_reporting/error_reporter.cc",
+ "certificate_reporting/error_reporter.h",
+ ]
+ },
+ {
+ # Protobuf compiler / generator for the certificate error reporting
+ # protocol buffer.
+ # GN version: //components/certificate_reporting:cert_logger_proto
+ 'target_name': 'cert_logger_proto',
+ 'type': 'static_library',
+ 'sources': [ 'certificate_reporting/cert_logger.proto', ],
+ 'variables': {
+ 'proto_in_dir': 'certificate_reporting/',
+ 'proto_out_dir': 'components/certificate_reporting/',
+ },
+ 'includes': [ '../build/protoc.gypi', ],
+ },
+ {
+ # Protobuf compiler / generator for the encrypted certificate
+ # reports protocol buffer.
+ # GN version: //components/certificate_reporting:encrypted_cert_logger_proto
+ 'target_name': 'encrypted_cert_logger_proto',
+ 'type': 'static_library',
+ 'sources': [ 'certificate_reporting/encrypted_cert_logger.proto', ],
+ 'variables': {
+ 'proto_in_dir': 'certificate_reporting/',
+ 'proto_out_dir': 'components/certificate_reporting/',
+ },
+ 'includes': [ '../build/protoc.gypi', ],
+ },
+ ]
+}
diff --git a/chromium/components/certificate_transparency.gypi b/chromium/components/certificate_transparency.gypi
new file mode 100644
index 00000000000..3b69f72219e
--- /dev/null
+++ b/chromium/components/certificate_transparency.gypi
@@ -0,0 +1,26 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/certificate_transparency
+ 'target_name': 'certificate_transparency',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../components/components.gyp:safe_json',
+ '../net/net.gyp:net',
+ '../url/url.gyp:url_lib',
+ ],
+ 'sources': [
+ 'certificate_transparency/log_proof_fetcher.h',
+ 'certificate_transparency/log_proof_fetcher.cc',
+ ],
+ }
+ ],
+}
diff --git a/chromium/components/chrome_apps/chrome_apps_resources.grd b/chromium/components/chrome_apps/chrome_apps_resources.grd
new file mode 100644
index 00000000000..725f0424ea4
--- /dev/null
+++ b/chromium/components/chrome_apps/chrome_apps_resources.grd
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0" current_release="1">
+ <outputs>
+ <output filename="grit/chrome_apps_resources.h" type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="grit/chrome_apps_resources_map.cc" type="resource_file_map_source" />
+ <output filename="grit/chrome_apps_resources_map.h" type="resource_map_header" />
+ <output filename="chrome_apps_resources.pak" type="data_package" />
+ <output filename="chrome_apps_resources.rc" type="rc_all" />
+ </outputs>
+ <release seq="1">
+ <includes>
+ <if expr="chromeos">
+ <part file="webstore_widget_resources.grdp" />
+ </if>
+ </includes>
+ </release>
+</grit>
diff --git a/chromium/components/chrome_apps/webstore_widget/app/compiled_resources.gyp b/chromium/components/chrome_apps/webstore_widget/app/compiled_resources.gyp
index 1fc7672d9bb..2477d32bd06 100644
--- a/chromium/components/chrome_apps/webstore_widget/app/compiled_resources.gyp
+++ b/chromium/components/chrome_apps/webstore_widget/app/compiled_resources.gyp
@@ -9,7 +9,7 @@
'depends': [
'<@(cws_widget_container)',
'../../../../third_party/jstemplate/compiled_resources.gyp:jstemplate',
- '../../../../ui/webui/resources/js/i18n_template_no_process.js',
+ '../../../../ui/webui/resources/js/compiled_resources.gyp:i18n_template_no_process',
'../../../../ui/webui/resources/js/load_time_data.js',
],
'externs': [
diff --git a/chromium/components/component_updater.gypi b/chromium/components/component_updater.gypi
index 124eb21f711..f90fa46cc12 100644
--- a/chromium/components/component_updater.gypi
+++ b/chromium/components/component_updater.gypi
@@ -13,6 +13,7 @@
'../ui/base/ui_base.gyp:ui_base',
'../url/url.gyp:url_lib',
'update_client',
+ 'version_info',
],
'include_dirs': [
'..',
@@ -25,6 +26,10 @@
'component_updater/component_updater_service_internal.h',
'component_updater/component_updater_switches.cc',
'component_updater/component_updater_switches.h',
+ 'component_updater/component_updater_url_constants.cc',
+ 'component_updater/component_updater_url_constants.h',
+ 'component_updater/configurator_impl.cc',
+ 'component_updater/configurator_impl.h',
'component_updater/default_component_installer.cc',
'component_updater/default_component_installer.h',
'component_updater/pref_names.cc',
diff --git a/chromium/components/components.gyp b/chromium/components/components.gyp
index 7b5a01ce0b5..4838a7032b3 100644
--- a/chromium/components/components.gyp
+++ b/chromium/components/components.gyp
@@ -10,17 +10,22 @@
'chromium_code': 1,
},
'includes': [
+ 'about_handler.gypi',
'auto_login_parser.gypi',
'autofill.gypi',
'bookmarks.gypi',
+ 'bubble.gypi',
'captive_portal.gypi',
+ 'certificate_reporting.gypi',
'cloud_devices.gypi',
'component_updater.gypi',
+ 'compression.gypi',
'content_settings.gypi',
'crash.gypi',
'cronet.gypi',
'crx_file.gypi',
'data_reduction_proxy.gypi',
+ 'data_use_measurement.gypi',
'device_event_log.gypi',
'dom_distiller.gypi',
'domain_reliability.gypi',
@@ -28,6 +33,7 @@
'error_page.gypi',
'favicon.gypi',
'favicon_base.gypi',
+ 'flags_ui.gypi',
'gcm_driver.gypi',
'google.gypi',
'guest_view.gypi',
@@ -40,13 +46,16 @@
'language_usage_metrics.gypi',
'leveldb_proto.gypi',
'login.gypi',
+ 'memory_pressure.gypi',
'metrics.gypi',
'navigation_metrics.gypi',
+ 'net_log.gypi',
'network_hints.gypi',
'network_time.gypi',
'offline_pages.gypi',
'omnibox.gypi',
'onc.gypi',
+ 'open_from_clipboard.gypi',
'os_crypt.gypi',
'ownership.gypi',
'packed_ct_ev_whitelist.gypi',
@@ -62,19 +71,24 @@
'search.gypi',
'search_engines.gypi',
'search_provider_logos.gypi',
+ 'security_interstitials.gypi',
'sessions.gypi',
'signin.gypi',
+ 'ssl_errors.gypi',
'startup_metric_utils.gypi',
'suggestions.gypi',
'sync_driver.gypi',
+ 'syncable_prefs.gypi',
+ 'toolbar.gypi',
'translate.gypi',
'ui_zoom.gypi',
'undo.gypi',
'update_client.gypi',
- 'url_fixer.gypi',
+ 'upload_list.gypi',
'url_matcher.gypi',
'user_prefs.gypi',
'variations.gypi',
+ 'version_info.gypi',
'wallpaper.gypi',
'web_resource.gypi',
'webdata.gypi',
@@ -92,10 +106,13 @@
'app_modal.gypi',
'browsing_data.gypi',
'cdm.gypi',
+ 'certificate_transparency.gypi',
'devtools_discovery.gypi',
'devtools_http_handler.gypi',
+ 'drive.gypi',
'message_port.gypi',
'navigation_interception.gypi',
+ 'page_load_metrics.gypi',
'power.gypi',
'safe_json.gypi',
'visitedlink.gypi',
@@ -106,7 +123,6 @@
}],
['OS == "ios"', {
'includes': [
- 'open_from_clipboard.gypi',
'webp_transcode.gypi',
],
}],
@@ -117,6 +133,7 @@
'feedback.gypi',
'proximity_auth.gypi',
'storage_monitor.gypi',
+ 'webusb.gypi',
]
}],
['chromeos == 1', {
@@ -164,5 +181,10 @@
'chrome_apps.gypi',
],
}],
+ ['enable_rlz_support==1', {
+ 'includes': [
+ 'rlz.gypi',
+ ],
+ }]
],
}
diff --git a/chromium/components/components_browsertests.isolate b/chromium/components/components_browsertests.isolate
index 0419dcd794d..c3ed0b48469 100644
--- a/chromium/components/components_browsertests.isolate
+++ b/chromium/components/components_browsertests.isolate
@@ -46,7 +46,6 @@
'variables': {
'files': [
'../testing/test_env.py',
- '<(PRODUCT_DIR)/components_browsertests<(EXECUTABLE_SUFFIX)',
'<(PRODUCT_DIR)/components_tests_resources.pak',
'<(PRODUCT_DIR)/content_shell.pak',
],
@@ -89,6 +88,6 @@
'includes': [
'../base/base.isolate',
'../gin/v8.isolate',
- '../third_party/angle/angle.isolate',
+ '../ui/gl/gl.isolate',
],
}
diff --git a/chromium/components/components_chromium_strings.grd b/chromium/components/components_chromium_strings.grd
new file mode 100644
index 00000000000..95622dff7ee
--- /dev/null
+++ b/chromium/components/components_chromium_strings.grd
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<grit latest_public_release="0" current_release="1"
+ source_lang_id="en" enc_check="möl">
+ <outputs>
+ <output filename="grit/components_chromium_strings.h" type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="components_chromium_strings_am.pak" type="data_package" lang="am" />
+ <output filename="components_chromium_strings_ar.pak" type="data_package" lang="ar" />
+ <output filename="components_chromium_strings_bg.pak" type="data_package" lang="bg" />
+ <output filename="components_chromium_strings_bn.pak" type="data_package" lang="bn" />
+ <output filename="components_chromium_strings_ca.pak" type="data_package" lang="ca" />
+ <output filename="components_chromium_strings_cs.pak" type="data_package" lang="cs" />
+ <output filename="components_chromium_strings_da.pak" type="data_package" lang="da" />
+ <output filename="components_chromium_strings_de.pak" type="data_package" lang="de" />
+ <output filename="components_chromium_strings_el.pak" type="data_package" lang="el" />
+ <output filename="components_chromium_strings_en-GB.pak" type="data_package" lang="en-GB" />
+ <output filename="components_chromium_strings_en-US.pak" type="data_package" lang="en" />
+ <output filename="components_chromium_strings_es.pak" type="data_package" lang="es" />
+ <if expr="is_ios">
+ <!-- iOS uses es-MX for es-419 -->
+ <output filename="components_chromium_strings_es-MX.pak" type="data_package" lang="es-419" />
+ </if>
+ <if expr="not is_ios">
+ <output filename="components_chromium_strings_es-419.pak" type="data_package" lang="es-419" />
+ </if>
+ <output filename="components_chromium_strings_et.pak" type="data_package" lang="et" />
+ <output filename="components_chromium_strings_fa.pak" type="data_package" lang="fa" />
+ <output filename="components_chromium_strings_fake-bidi.pak" type="data_package" lang="fake-bidi" />
+ <output filename="components_chromium_strings_fi.pak" type="data_package" lang="fi" />
+ <output filename="components_chromium_strings_fil.pak" type="data_package" lang="fil" />
+ <output filename="components_chromium_strings_fr.pak" type="data_package" lang="fr" />
+ <output filename="components_chromium_strings_gu.pak" type="data_package" lang="gu" />
+ <output filename="components_chromium_strings_he.pak" type="data_package" lang="he" />
+ <output filename="components_chromium_strings_hi.pak" type="data_package" lang="hi" />
+ <output filename="components_chromium_strings_hr.pak" type="data_package" lang="hr" />
+ <output filename="components_chromium_strings_hu.pak" type="data_package" lang="hu" />
+ <output filename="components_chromium_strings_id.pak" type="data_package" lang="id" />
+ <output filename="components_chromium_strings_it.pak" type="data_package" lang="it" />
+ <output filename="components_chromium_strings_ja.pak" type="data_package" lang="ja" />
+ <output filename="components_chromium_strings_kn.pak" type="data_package" lang="kn" />
+ <output filename="components_chromium_strings_ko.pak" type="data_package" lang="ko" />
+ <output filename="components_chromium_strings_lt.pak" type="data_package" lang="lt" />
+ <output filename="components_chromium_strings_lv.pak" type="data_package" lang="lv" />
+ <output filename="components_chromium_strings_ml.pak" type="data_package" lang="ml" />
+ <output filename="components_chromium_strings_mr.pak" type="data_package" lang="mr" />
+ <output filename="components_chromium_strings_ms.pak" type="data_package" lang="ms" />
+ <output filename="components_chromium_strings_nl.pak" type="data_package" lang="nl" />
+ <!-- The translation console uses 'no' for Norwegian Bokmål. It should
+ be 'nb'. -->
+ <output filename="components_chromium_strings_nb.pak" type="data_package" lang="no" />
+ <output filename="components_chromium_strings_pl.pak" type="data_package" lang="pl" />
+ <if expr="is_ios">
+ <!-- iOS uses pt for pt-BR -->
+ <output filename="components_chromium_strings_pt.pak" type="data_package" lang="pt-BR" />
+ </if>
+ <if expr="not is_ios">
+ <output filename="components_chromium_strings_pt-BR.pak" type="data_package" lang="pt-BR" />
+ </if>
+ <output filename="components_chromium_strings_pt-PT.pak" type="data_package" lang="pt-PT" />
+ <output filename="components_chromium_strings_ro.pak" type="data_package" lang="ro" />
+ <output filename="components_chromium_strings_ru.pak" type="data_package" lang="ru" />
+ <output filename="components_chromium_strings_sk.pak" type="data_package" lang="sk" />
+ <output filename="components_chromium_strings_sl.pak" type="data_package" lang="sl" />
+ <output filename="components_chromium_strings_sr.pak" type="data_package" lang="sr" />
+ <output filename="components_chromium_strings_sv.pak" type="data_package" lang="sv" />
+ <output filename="components_chromium_strings_sw.pak" type="data_package" lang="sw" />
+ <output filename="components_chromium_strings_ta.pak" type="data_package" lang="ta" />
+ <output filename="components_chromium_strings_te.pak" type="data_package" lang="te" />
+ <output filename="components_chromium_strings_th.pak" type="data_package" lang="th" />
+ <output filename="components_chromium_strings_tr.pak" type="data_package" lang="tr" />
+ <output filename="components_chromium_strings_uk.pak" type="data_package" lang="uk" />
+ <output filename="components_chromium_strings_vi.pak" type="data_package" lang="vi" />
+ <output filename="components_chromium_strings_zh-CN.pak" type="data_package" lang="zh-CN" />
+ <output filename="components_chromium_strings_zh-TW.pak" type="data_package" lang="zh-TW" />
+ </outputs>
+ <translations>
+ <file path="strings/components_chromium_strings_am.xtb" lang="am" />
+ <file path="strings/components_chromium_strings_ar.xtb" lang="ar" />
+ <file path="strings/components_chromium_strings_bg.xtb" lang="bg" />
+ <file path="strings/components_chromium_strings_bn.xtb" lang="bn" />
+ <file path="strings/components_chromium_strings_ca.xtb" lang="ca" />
+ <file path="strings/components_chromium_strings_cs.xtb" lang="cs" />
+ <file path="strings/components_chromium_strings_da.xtb" lang="da" />
+ <file path="strings/components_chromium_strings_de.xtb" lang="de" />
+ <file path="strings/components_chromium_strings_el.xtb" lang="el" />
+ <file path="strings/components_chromium_strings_en-GB.xtb" lang="en-GB" />
+ <file path="strings/components_chromium_strings_es.xtb" lang="es" />
+ <file path="strings/components_chromium_strings_es-419.xtb" lang="es-419" />
+ <file path="strings/components_chromium_strings_et.xtb" lang="et" />
+ <file path="strings/components_chromium_strings_fa.xtb" lang="fa" />
+ <file path="strings/components_chromium_strings_fi.xtb" lang="fi" />
+ <file path="strings/components_chromium_strings_fil.xtb" lang="fil" />
+ <file path="strings/components_chromium_strings_fr.xtb" lang="fr" />
+ <file path="strings/components_chromium_strings_gu.xtb" lang="gu" />
+ <file path="strings/components_chromium_strings_hi.xtb" lang="hi" />
+ <file path="strings/components_chromium_strings_hr.xtb" lang="hr" />
+ <file path="strings/components_chromium_strings_hu.xtb" lang="hu" />
+ <file path="strings/components_chromium_strings_id.xtb" lang="id" />
+ <file path="strings/components_chromium_strings_it.xtb" lang="it" />
+ <!-- The translation console uses 'iw' for Hebrew, but we use 'he'. -->
+ <file path="strings/components_chromium_strings_iw.xtb" lang="he" />
+ <file path="strings/components_chromium_strings_ja.xtb" lang="ja" />
+ <file path="strings/components_chromium_strings_kn.xtb" lang="kn" />
+ <file path="strings/components_chromium_strings_ko.xtb" lang="ko" />
+ <file path="strings/components_chromium_strings_lt.xtb" lang="lt" />
+ <file path="strings/components_chromium_strings_lv.xtb" lang="lv" />
+ <file path="strings/components_chromium_strings_ml.xtb" lang="ml" />
+ <file path="strings/components_chromium_strings_mr.xtb" lang="mr" />
+ <file path="strings/components_chromium_strings_ms.xtb" lang="ms" />
+ <file path="strings/components_chromium_strings_nl.xtb" lang="nl" />
+ <file path="strings/components_chromium_strings_no.xtb" lang="no" />
+ <file path="strings/components_chromium_strings_pl.xtb" lang="pl" />
+ <file path="strings/components_chromium_strings_pt-BR.xtb" lang="pt-BR" />
+ <file path="strings/components_chromium_strings_pt-PT.xtb" lang="pt-PT" />
+ <file path="strings/components_chromium_strings_ro.xtb" lang="ro" />
+ <file path="strings/components_chromium_strings_ru.xtb" lang="ru" />
+ <file path="strings/components_chromium_strings_sk.xtb" lang="sk" />
+ <file path="strings/components_chromium_strings_sl.xtb" lang="sl" />
+ <file path="strings/components_chromium_strings_sr.xtb" lang="sr" />
+ <file path="strings/components_chromium_strings_sv.xtb" lang="sv" />
+ <file path="strings/components_chromium_strings_sw.xtb" lang="sw" />
+ <file path="strings/components_chromium_strings_ta.xtb" lang="ta" />
+ <file path="strings/components_chromium_strings_te.xtb" lang="te" />
+ <file path="strings/components_chromium_strings_th.xtb" lang="th" />
+ <file path="strings/components_chromium_strings_tr.xtb" lang="tr" />
+ <file path="strings/components_chromium_strings_uk.xtb" lang="uk" />
+ <file path="strings/components_chromium_strings_vi.xtb" lang="vi" />
+ <file path="strings/components_chromium_strings_zh-CN.xtb" lang="zh-CN" />
+ <file path="strings/components_chromium_strings_zh-TW.xtb" lang="zh-TW" />
+ </translations>
+ <release seq="1" allow_pseudo="false">
+ <messages fallback_to_english="true">
+ <!-- Network Error Pages -->
+ <if expr="not is_android">
+ <message name="IDS_ERRORPAGES_SUGGESTION_NETWORK_PREDICTION_BODY" desc="When a page fails to load, sometimes we suggest disabling predicting network actions. These are details below a header for non Android devices.">
+ Go to
+ the Chromium menu &gt;
+ <ph name="SETTINGS_TITLE">&lt;span jscontent="settingsTitle"&gt;&lt;/span&gt;<ex>Settings</ex></ph>
+ &gt;
+ <ph name="ADVANCED_TITLE">&lt;span jscontent="advancedTitle"&gt;&lt;/span&gt;<ex>Under the Hood</ex></ph>
+ and deselect &quot;<ph name="NO_PREFETCH_DESCRIPTION">&lt;span jscontent="noNetworkPredictionTitle"&gt;&lt;/span&gt;<ex>Prefetch resources to load pages more quickly</ex></ph>.&quot;
+ If this does not resolve the issue, we recommend selecting this option
+ again for improved performance.
+ </message>
+ </if>
+ <if expr="is_android">
+ <message name="IDS_ERRORPAGES_SUGGESTION_NETWORK_PREDICTION_BODY" desc="When a page fails to load, sometimes we suggest disabling predicting network actions. These are details below a header for Android devices. Note that on devices without mobile network (3G) capability, the setting is a checkbox, while on other devices, it is a list of three items. The words _disable_ and _re-enabling_ can be used for both cases.">
+ Go to the Chromium menu &gt; Settings &gt; (Advanced) Privacy
+ and disable &quot;Prefetch page resources.&quot;
+ If this does not resolve the issue, we recommend re-enabling this option
+ again for improved performance.
+ </message>
+ </if>
+
+ <!-- About Flags UI -->
+ <if expr="not chromeos">
+ <message name="IDS_FLAGS_UI_RELAUNCH_NOTICE" desc="Notifies the user that he needs to relaunch Chromium. Shown next to a button that says 'Relaunch Now'.">
+ Your changes will take effect the next time you relaunch Chromium.
+ </message>
+ </if>
+ <if expr="chromeos">
+ <message name="IDS_FLAGS_UI_RELAUNCH_NOTICE" desc="Notifies the user that he needs to restart Chromium OS. Shown next to a button that says 'Restart Now'.">
+ Your changes will take effect the next time you restart your device.
+ </message>
+ </if>
+ </messages>
+ </release>
+</grit>
diff --git a/chromium/components/components_google_chrome_strings.grd b/chromium/components/components_google_chrome_strings.grd
new file mode 100644
index 00000000000..2076a56ce75
--- /dev/null
+++ b/chromium/components/components_google_chrome_strings.grd
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<grit latest_public_release="0" current_release="1"
+ source_lang_id="en" enc_check="möl">
+ <outputs>
+ <output filename="grit/components_google_chrome_strings.h" type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="components_google_chrome_strings_am.pak" type="data_package" lang="am" />
+ <output filename="components_google_chrome_strings_ar.pak" type="data_package" lang="ar" />
+ <output filename="components_google_chrome_strings_bg.pak" type="data_package" lang="bg" />
+ <output filename="components_google_chrome_strings_bn.pak" type="data_package" lang="bn" />
+ <output filename="components_google_chrome_strings_ca.pak" type="data_package" lang="ca" />
+ <output filename="components_google_chrome_strings_cs.pak" type="data_package" lang="cs" />
+ <output filename="components_google_chrome_strings_da.pak" type="data_package" lang="da" />
+ <output filename="components_google_chrome_strings_de.pak" type="data_package" lang="de" />
+ <output filename="components_google_chrome_strings_el.pak" type="data_package" lang="el" />
+ <output filename="components_google_chrome_strings_en-GB.pak" type="data_package" lang="en-GB" />
+ <output filename="components_google_chrome_strings_en-US.pak" type="data_package" lang="en" />
+ <output filename="components_google_chrome_strings_es.pak" type="data_package" lang="es" />
+ <if expr="is_ios">
+ <!-- iOS uses es-MX for es-419 -->
+ <output filename="components_google_chrome_strings_es-MX.pak" type="data_package" lang="es-419" />
+ </if>
+ <if expr="not is_ios">
+ <output filename="components_google_chrome_strings_es-419.pak" type="data_package" lang="es-419" />
+ </if>
+ <output filename="components_google_chrome_strings_et.pak" type="data_package" lang="et" />
+ <output filename="components_google_chrome_strings_fa.pak" type="data_package" lang="fa" />
+ <output filename="components_google_chrome_strings_fake-bidi.pak" type="data_package" lang="fake-bidi" />
+ <output filename="components_google_chrome_strings_fi.pak" type="data_package" lang="fi" />
+ <output filename="components_google_chrome_strings_fil.pak" type="data_package" lang="fil" />
+ <output filename="components_google_chrome_strings_fr.pak" type="data_package" lang="fr" />
+ <output filename="components_google_chrome_strings_gu.pak" type="data_package" lang="gu" />
+ <output filename="components_google_chrome_strings_he.pak" type="data_package" lang="he" />
+ <output filename="components_google_chrome_strings_hi.pak" type="data_package" lang="hi" />
+ <output filename="components_google_chrome_strings_hr.pak" type="data_package" lang="hr" />
+ <output filename="components_google_chrome_strings_hu.pak" type="data_package" lang="hu" />
+ <output filename="components_google_chrome_strings_id.pak" type="data_package" lang="id" />
+ <output filename="components_google_chrome_strings_it.pak" type="data_package" lang="it" />
+ <output filename="components_google_chrome_strings_ja.pak" type="data_package" lang="ja" />
+ <output filename="components_google_chrome_strings_kn.pak" type="data_package" lang="kn" />
+ <output filename="components_google_chrome_strings_ko.pak" type="data_package" lang="ko" />
+ <output filename="components_google_chrome_strings_lt.pak" type="data_package" lang="lt" />
+ <output filename="components_google_chrome_strings_lv.pak" type="data_package" lang="lv" />
+ <output filename="components_google_chrome_strings_ml.pak" type="data_package" lang="ml" />
+ <output filename="components_google_chrome_strings_mr.pak" type="data_package" lang="mr" />
+ <output filename="components_google_chrome_strings_ms.pak" type="data_package" lang="ms" />
+ <output filename="components_google_chrome_strings_nl.pak" type="data_package" lang="nl" />
+ <!-- The translation console uses 'no' for Norwegian Bokmål. It should
+ be 'nb'. -->
+ <output filename="components_google_chrome_strings_nb.pak" type="data_package" lang="no" />
+ <output filename="components_google_chrome_strings_pl.pak" type="data_package" lang="pl" />
+ <if expr="is_ios">
+ <!-- iOS uses pt for pt-BR -->
+ <output filename="components_google_chrome_strings_pt.pak" type="data_package" lang="pt-BR" />
+ </if>
+ <if expr="not is_ios">
+ <output filename="components_google_chrome_strings_pt-BR.pak" type="data_package" lang="pt-BR" />
+ </if>
+ <output filename="components_google_chrome_strings_pt-PT.pak" type="data_package" lang="pt-PT" />
+ <output filename="components_google_chrome_strings_ro.pak" type="data_package" lang="ro" />
+ <output filename="components_google_chrome_strings_ru.pak" type="data_package" lang="ru" />
+ <output filename="components_google_chrome_strings_sk.pak" type="data_package" lang="sk" />
+ <output filename="components_google_chrome_strings_sl.pak" type="data_package" lang="sl" />
+ <output filename="components_google_chrome_strings_sr.pak" type="data_package" lang="sr" />
+ <output filename="components_google_chrome_strings_sv.pak" type="data_package" lang="sv" />
+ <output filename="components_google_chrome_strings_sw.pak" type="data_package" lang="sw" />
+ <output filename="components_google_chrome_strings_ta.pak" type="data_package" lang="ta" />
+ <output filename="components_google_chrome_strings_te.pak" type="data_package" lang="te" />
+ <output filename="components_google_chrome_strings_th.pak" type="data_package" lang="th" />
+ <output filename="components_google_chrome_strings_tr.pak" type="data_package" lang="tr" />
+ <output filename="components_google_chrome_strings_uk.pak" type="data_package" lang="uk" />
+ <output filename="components_google_chrome_strings_vi.pak" type="data_package" lang="vi" />
+ <output filename="components_google_chrome_strings_zh-CN.pak" type="data_package" lang="zh-CN" />
+ <output filename="components_google_chrome_strings_zh-TW.pak" type="data_package" lang="zh-TW" />
+ </outputs>
+ <translations>
+ <file path="strings/components_google_chrome_strings_am.xtb" lang="am" />
+ <file path="strings/components_google_chrome_strings_ar.xtb" lang="ar" />
+ <file path="strings/components_google_chrome_strings_bg.xtb" lang="bg" />
+ <file path="strings/components_google_chrome_strings_bn.xtb" lang="bn" />
+ <file path="strings/components_google_chrome_strings_ca.xtb" lang="ca" />
+ <file path="strings/components_google_chrome_strings_cs.xtb" lang="cs" />
+ <file path="strings/components_google_chrome_strings_da.xtb" lang="da" />
+ <file path="strings/components_google_chrome_strings_de.xtb" lang="de" />
+ <file path="strings/components_google_chrome_strings_el.xtb" lang="el" />
+ <file path="strings/components_google_chrome_strings_en-GB.xtb" lang="en-GB" />
+ <file path="strings/components_google_chrome_strings_es.xtb" lang="es" />
+ <file path="strings/components_google_chrome_strings_es-419.xtb" lang="es-419" />
+ <file path="strings/components_google_chrome_strings_et.xtb" lang="et" />
+ <file path="strings/components_google_chrome_strings_fa.xtb" lang="fa" />
+ <file path="strings/components_google_chrome_strings_fi.xtb" lang="fi" />
+ <file path="strings/components_google_chrome_strings_fil.xtb" lang="fil" />
+ <file path="strings/components_google_chrome_strings_fr.xtb" lang="fr" />
+ <file path="strings/components_google_chrome_strings_gu.xtb" lang="gu" />
+ <file path="strings/components_google_chrome_strings_hi.xtb" lang="hi" />
+ <file path="strings/components_google_chrome_strings_hr.xtb" lang="hr" />
+ <file path="strings/components_google_chrome_strings_hu.xtb" lang="hu" />
+ <file path="strings/components_google_chrome_strings_id.xtb" lang="id" />
+ <file path="strings/components_google_chrome_strings_it.xtb" lang="it" />
+ <!-- The translation console uses 'iw' for Hebrew, but we use 'he'. -->
+ <file path="strings/components_google_chrome_strings_iw.xtb" lang="he" />
+ <file path="strings/components_google_chrome_strings_ja.xtb" lang="ja" />
+ <file path="strings/components_google_chrome_strings_kn.xtb" lang="kn" />
+ <file path="strings/components_google_chrome_strings_ko.xtb" lang="ko" />
+ <file path="strings/components_google_chrome_strings_lt.xtb" lang="lt" />
+ <file path="strings/components_google_chrome_strings_lv.xtb" lang="lv" />
+ <file path="strings/components_google_chrome_strings_ml.xtb" lang="ml" />
+ <file path="strings/components_google_chrome_strings_mr.xtb" lang="mr" />
+ <file path="strings/components_google_chrome_strings_ms.xtb" lang="ms" />
+ <file path="strings/components_google_chrome_strings_nl.xtb" lang="nl" />
+ <file path="strings/components_google_chrome_strings_no.xtb" lang="no" />
+ <file path="strings/components_google_chrome_strings_pl.xtb" lang="pl" />
+ <file path="strings/components_google_chrome_strings_pt-BR.xtb" lang="pt-BR" />
+ <file path="strings/components_google_chrome_strings_pt-PT.xtb" lang="pt-PT" />
+ <file path="strings/components_google_chrome_strings_ro.xtb" lang="ro" />
+ <file path="strings/components_google_chrome_strings_ru.xtb" lang="ru" />
+ <file path="strings/components_google_chrome_strings_sk.xtb" lang="sk" />
+ <file path="strings/components_google_chrome_strings_sl.xtb" lang="sl" />
+ <file path="strings/components_google_chrome_strings_sr.xtb" lang="sr" />
+ <file path="strings/components_google_chrome_strings_sv.xtb" lang="sv" />
+ <file path="strings/components_google_chrome_strings_sw.xtb" lang="sw" />
+ <file path="strings/components_google_chrome_strings_ta.xtb" lang="ta" />
+ <file path="strings/components_google_chrome_strings_te.xtb" lang="te" />
+ <file path="strings/components_google_chrome_strings_th.xtb" lang="th" />
+ <file path="strings/components_google_chrome_strings_tr.xtb" lang="tr" />
+ <file path="strings/components_google_chrome_strings_uk.xtb" lang="uk" />
+ <file path="strings/components_google_chrome_strings_vi.xtb" lang="vi" />
+ <file path="strings/components_google_chrome_strings_zh-CN.xtb" lang="zh-CN" />
+ <file path="strings/components_google_chrome_strings_zh-TW.xtb" lang="zh-TW" />
+ </translations>
+ <release seq="1" allow_pseudo="false">
+ <messages fallback_to_english="true">
+ <!-- Network Error Pages -->
+ <if expr="not is_android">
+ <message name="IDS_ERRORPAGES_SUGGESTION_NETWORK_PREDICTION_BODY" desc="When a page fails to load, sometimes we suggest disabling predicting network actions. These are details below a header for non Android devices.">
+ Go to
+ the Chrome menu &gt;
+ <ph name="SETTINGS_TITLE">&lt;span jscontent="settingsTitle"&gt;&lt;/span&gt;<ex>Settings</ex></ph>
+ &gt;
+ <ph name="ADVANCED_TITLE">&lt;span jscontent="advancedTitle"&gt;&lt;/span&gt;<ex>Under the Hood</ex></ph>
+ and deselect &quot;<ph name="NO_PREFETCH_DESCRIPTION">&lt;span jscontent="noNetworkPredictionTitle"&gt;&lt;/span&gt;<ex>Prefetch resources to load pages more quickly</ex></ph>.&quot;
+ If this does not resolve the issue, we recommend selecting this option
+ again for improved performance.
+ </message>
+ </if>
+ <if expr="is_android">
+ <message name="IDS_ERRORPAGES_SUGGESTION_NETWORK_PREDICTION_BODY" desc="When a page fails to load, sometimes we suggest disabling predicting network actions. These are details below a header for Android devices. Note that on devices without mobile network (3G) capability, the setting is a checkbox, while on other devices, it is a list of three items. The words _disable_ and _re-enabling_ can be used for both cases.">
+ Go to the Chrome menu &gt; Settings &gt; (Advanced) Privacy
+ and disable &quot;Prefetch page resources.&quot;
+ If this does not resolve the issue, we recommend re-enabling this option
+ again for improved performance.
+ </message>
+ </if>
+
+ <!-- About Flags UI -->
+ <if expr="not chromeos">
+ <message name="IDS_FLAGS_UI_RELAUNCH_NOTICE" desc="Notifies the user that he needs to relaunch Chrome. Shown next to a button that says 'Relaunch Now'.">
+ Your changes will take effect the next time you relaunch Google Chrome.
+ </message>
+ </if>
+ <if expr="chromeos">
+ <message name="IDS_FLAGS_UI_RELAUNCH_NOTICE" desc="Notifies the user that he needs to restart Chrome OS. Shown next to a button that says 'Restart Now'.">
+ Your changes will take effect the next time you restart your device.
+ </message>
+ </if>
+
+ </messages>
+ </release>
+</grit>
diff --git a/chromium/components/components_resources.gyp b/chromium/components/components_resources.gyp
index 52f9fe99226..c2568d02a69 100644
--- a/chromium/components/components_resources.gyp
+++ b/chromium/components/components_resources.gyp
@@ -3,11 +3,17 @@
# found in the LICENSE file.
{
+ 'variables': {
+ 'about_credits_file': '<(SHARED_INTERMEDIATE_DIR)/about_credits.html',
+ },
'targets': [
{
# GN version: //components/resources
'target_name': 'components_resources',
'type': 'none',
+ 'dependencies': [
+ 'about_credits',
+ ],
'variables': {
'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/components',
},
@@ -16,7 +22,11 @@
# GN version: //components/resources:components_resources
'action_name': 'generate_components_resources',
'variables': {
+ 'grit_whitelist': '',
'grit_grd_file': 'resources/components_resources.grd',
+ 'grit_additional_defines': [
+ '-E', 'about_credits_file=<(about_credits_file)',
+ ],
},
'includes': [ '../build/grit_action.gypi' ],
},
@@ -24,6 +34,7 @@
# GN version: //components/resources:components_scaled_resources
'action_name': 'generate_components_scaled_resources',
'variables': {
+ 'grit_whitelist': '',
'grit_grd_file': 'resources/components_scaled_resources.grd',
},
'includes': [ '../build/grit_action.gypi' ],
@@ -31,5 +42,35 @@
],
'includes': [ '../build/grit_target.gypi' ],
},
+ {
+ # GN version: //components/resources:about_credits
+ 'target_name': 'about_credits',
+ 'type': 'none',
+ 'actions': [
+ {
+ 'variables': {
+ 'generator_path': '../tools/licenses.py',
+ },
+ 'action_name': 'generate_about_credits',
+ 'inputs': [
+ # TODO(phajdan.jr): make licenses.py print license input files so
+ # about:credits gets rebuilt when one changes.
+ '<(generator_path)',
+ 'about_ui/resources/about_credits.tmpl',
+ 'about_ui/resources/about_credits_entry.tmpl',
+ ],
+ 'outputs': [
+ '<(about_credits_file)',
+ ],
+ 'hard_dependency': 1,
+ 'action': ['python',
+ '<(generator_path)',
+ 'credits',
+ '<(about_credits_file)',
+ ],
+ 'message': 'Generating about:credits',
+ },
+ ],
+ },
],
}
diff --git a/chromium/components/components_strings.grd b/chromium/components/components_strings.grd
index 2df5848367c..f71b63da7e0 100644
--- a/chromium/components/components_strings.grd
+++ b/chromium/components/components_strings.grd
@@ -8,30 +8,15 @@
</output>
<output filename="components_strings_am.pak" type="data_package" lang="am" />
<output filename="components_strings_ar.pak" type="data_package" lang="ar" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_ast.pak" type="data_package" lang="ast" />
- </if>
<output filename="components_strings_bg.pak" type="data_package" lang="bg" />
<output filename="components_strings_bn.pak" type="data_package" lang="bn" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_bs.pak" type="data_package" lang="bs" />
- </if>
<output filename="components_strings_ca.pak" type="data_package" lang="ca" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_ca@valencia.pak" type="data_package" lang="ca@valencia" />
- </if>
<output filename="components_strings_cs.pak" type="data_package" lang="cs" />
<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" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_en-AU.pak" type="data_package" lang="en-AU" />
- </if>
<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" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_eo.pak" type="data_package" lang="eo" />
- </if>
<output filename="components_strings_es.pak" type="data_package" lang="es" />
<if expr="is_ios">
<!-- iOS uses es-MX for es-419 -->
@@ -41,38 +26,21 @@
<output filename="components_strings_es-419.pak" type="data_package" lang="es-419" />
</if>
<output filename="components_strings_et.pak" type="data_package" lang="et" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_eu.pak" type="data_package" lang="eu" />
- </if>
<output filename="components_strings_fa.pak" type="data_package" lang="fa" />
<output filename="components_strings_fake-bidi.pak" type="data_package" lang="fake-bidi" />
<output filename="components_strings_fi.pak" type="data_package" lang="fi" />
<output filename="components_strings_fil.pak" type="data_package" lang="fil" />
<output filename="components_strings_fr.pak" type="data_package" lang="fr" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_gl.pak" type="data_package" lang="gl" />
- </if>
<output filename="components_strings_gu.pak" type="data_package" lang="gu" />
<output filename="components_strings_he.pak" type="data_package" lang="he" />
<output filename="components_strings_hi.pak" type="data_package" lang="hi" />
<output filename="components_strings_hr.pak" type="data_package" lang="hr" />
<output filename="components_strings_hu.pak" type="data_package" lang="hu" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_hy.pak" type="data_package" lang="hy" />
- <output filename="components_strings_ia.pak" type="data_package" lang="ia" />
- </if>
<output filename="components_strings_id.pak" type="data_package" lang="id" />
<output filename="components_strings_it.pak" type="data_package" lang="it" />
<output filename="components_strings_ja.pak" type="data_package" lang="ja" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_ka.pak" type="data_package" lang="ka" />
- </if>
<output filename="components_strings_kn.pak" type="data_package" lang="kn" />
<output filename="components_strings_ko.pak" type="data_package" lang="ko" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_ku.pak" type="data_package" lang="ku" />
- <output filename="components_strings_kw.pak" type="data_package" lang="kw" />
- </if>
<output filename="components_strings_lt.pak" type="data_package" lang="lt" />
<output filename="components_strings_lv.pak" type="data_package" lang="lv" />
<output filename="components_strings_ml.pak" type="data_package" lang="ml" />
@@ -102,9 +70,6 @@
<output filename="components_strings_te.pak" type="data_package" lang="te" />
<output filename="components_strings_th.pak" type="data_package" lang="th" />
<output filename="components_strings_tr.pak" type="data_package" lang="tr" />
- <if expr="use_third_party_translations">
- <output filename="components_strings_ug.pak" type="data_package" lang="ug" />
- </if>
<output filename="components_strings_uk.pak" type="data_package" lang="uk" />
<output filename="components_strings_vi.pak" type="data_package" lang="vi" />
<output filename="components_strings_zh-CN.pak" type="data_package" lang="zh-CN" />
@@ -173,13 +138,16 @@
<part file="data_reduction_proxy_strings.grdp" />
<part file="dom_distiller_strings.grdp" />
<part file="error_page_strings.grdp" />
+ <part file="flags_ui_strings.grdp" />
<part file="omnibox_strings.grdp" />
- <part file="open_from_clipboard_strings.grdp" />
<part file="password_manager_strings.grdp" />
<part file="pdf_strings.grdp" />
<part file="policy_strings.grdp" />
+ <part file="security_interstitials_strings.grdp" />
+ <part file="ssl_errors_strings.grdp" />
<part file="translate_strings.grdp" />
<part file="undo_strings.grdp" />
+ <part file="version_info.grdp" />
<!-- Generic terms -->
<message name="IDS_LEARN_MORE" desc="Learn more text">
diff --git a/chromium/components/components_strings.gyp b/chromium/components/components_strings.gyp
index 1373f2e7fb0..31789acc62b 100644
--- a/chromium/components/components_strings.gyp
+++ b/chromium/components/components_strings.gyp
@@ -5,7 +5,6 @@
{
'targets': [
{
- # GN version: //components/strings
'target_name': 'components_strings',
'type': 'none',
'variables': {
@@ -13,12 +12,32 @@
},
'actions': [
{
+ # GN version: //components/strings:components_strings
'action_name': 'generate_components_strings',
'variables': {
+ 'grit_whitelist': '',
'grit_grd_file': 'components_strings.grd',
},
'includes': [ '../build/grit_action.gypi' ],
},
+ {
+ # GN version: //components/strings:components_chromium_strings
+ 'action_name': 'generate_components_chromium_strings',
+ 'variables': {
+ 'grit_whitelist': '',
+ 'grit_grd_file': 'components_chromium_strings.grd',
+ },
+ 'includes': [ '../build/grit_action.gypi' ],
+ },
+ {
+ # GN version: //components/strings:components_google_chrome_strings
+ 'action_name': 'generate_components_google_chrome_strings',
+ 'variables': {
+ 'grit_whitelist': '',
+ 'grit_grd_file': 'components_google_chrome_strings.grd',
+ },
+ 'includes': [ '../build/grit_action.gypi' ],
+ },
],
'includes': [ '../build/grit_target.gypi' ],
},
diff --git a/chromium/components/components_tests.gyp b/chromium/components/components_tests.gyp
index 4dd484687bf..d6744af715d 100644
--- a/chromium/components/components_tests.gyp
+++ b/chromium/components/components_tests.gyp
@@ -11,7 +11,7 @@
# Note: sources list duplicated in GN build. In the GN build,
# each component has its own unit tests target defined in its
- # directory that are then linked into the final content_unittests.
+ # directory that are then linked into the final components_unittests.
'auto_login_parser_unittest_sources': [
'auto_login_parser/auto_login_parser_unittest.cc',
],
@@ -19,13 +19,9 @@
'autofill/content/browser/content_autofill_driver_unittest.cc',
'autofill/content/browser/request_autocomplete_manager_unittest.cc',
'autofill/content/browser/wallet/full_wallet_unittest.cc',
- 'autofill/content/browser/wallet/instrument_unittest.cc',
'autofill/content/browser/wallet/real_pan_wallet_client_unittest.cc',
'autofill/content/browser/wallet/wallet_address_unittest.cc',
- 'autofill/content/browser/wallet/wallet_client_unittest.cc',
- 'autofill/content/browser/wallet/wallet_items_unittest.cc',
'autofill/content/browser/wallet/wallet_service_url_unittest.cc',
- 'autofill/content/browser/wallet/wallet_signin_helper_unittest.cc',
'autofill/content/renderer/renderer_save_password_progress_logger_unittest.cc',
'autofill/core/browser/address_field_unittest.cc',
'autofill/core/browser/address_i18n_unittest.cc',
@@ -62,6 +58,7 @@
'autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service_unittest.cc',
'autofill/core/browser/webdata/web_data_service_unittest.cc',
'autofill/core/common/autofill_regexes_unittest.cc',
+ 'autofill/core/common/autofill_util_unittest.cc',
'autofill/core/common/form_data_unittest.cc',
'autofill/core/common/form_field_data_unittest.cc',
'autofill/core/common/password_form_fill_data_unittest.cc',
@@ -84,9 +81,21 @@
'browser_watcher/watcher_metrics_provider_win_unittest.cc',
'browser_watcher/window_hang_monitor_win_unittest.cc',
],
+ 'bubble_unittest_sources': [
+ 'bubble/bubble_manager_mocks.cc',
+ 'bubble/bubble_manager_mocks.h',
+ 'bubble/bubble_manager_unittest.cc',
+ ],
'captive_portal_unittest_sources': [
'captive_portal/captive_portal_detector_unittest.cc',
],
+ 'certificate_reporting_unittest_sources': [
+ 'certificate_reporting/error_report_unittest.cc',
+ 'certificate_reporting/error_reporter_unittest.cc',
+ ],
+ 'certificate_transparency_unittest_sources': [
+ 'certificate_transparency/log_proof_fetcher_unittest.cc',
+ ],
'cloud_devices_unittest_sources': [
'cloud_devices/common/cloud_devices_urls_unittest.cc',
'cloud_devices/common/printer_description_unittest.cc',
@@ -95,19 +104,23 @@
'component_updater/component_updater_service_unittest.cc',
'component_updater/timer_unittest.cc',
],
+ 'compression_unittest_sources': [
+ 'compression/compression_utils_unittest.cc',
+ ],
'content_settings_unittest_sources': [
'content_settings/core/browser/content_settings_mock_provider.cc',
'content_settings/core/browser/content_settings_mock_provider.h',
- 'content_settings/core/browser/content_settings_provider_unittest.cc',
+ 'content_settings/core/browser/content_settings_registry_unittest.cc',
'content_settings/core/browser/content_settings_rule_unittest.cc',
'content_settings/core/browser/content_settings_utils_unittest.cc',
'content_settings/core/browser/cookie_settings_unittest.cc',
- 'content_settings/core/browser/plugins_field_trial_unittest.cc',
+ 'content_settings/core/browser/website_settings_registry_unittest.cc',
'content_settings/core/common/content_settings_pattern_parser_unittest.cc',
'content_settings/core/common/content_settings_pattern_unittest.cc',
],
'crash_unittest_sources': [
- 'crash/app/crash_keys_win_unittest.cc',
+ 'crash/content/app/crash_keys_win_unittest.cc',
+ 'crash/core/common/objc_zombie_unittest.mm',
],
'crx_file_unittest_sources': [
'crx_file/id_util_unittest.cc',
@@ -125,6 +138,7 @@
'data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc',
'data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc',
'data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc',
+ 'data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values_unittest.cc',
'data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc',
'data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc',
'data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc',
@@ -143,8 +157,8 @@
'devtools_http_handler/devtools_http_handler_unittest.cc',
],
'dom_distiller_unittest_sources': [
- 'dom_distiller/content/dom_distiller_viewer_source_unittest.cc',
- 'dom_distiller/content/web_contents_main_frame_observer_unittest.cc',
+ 'dom_distiller/content/browser/dom_distiller_viewer_source_unittest.cc',
+ 'dom_distiller/content/browser/web_contents_main_frame_observer_unittest.cc',
'dom_distiller/core/article_entry_unittest.cc',
'dom_distiller/core/distillable_page_detector_unittest.cc',
'dom_distiller/core/distilled_content_store_unittest.cc',
@@ -187,7 +201,6 @@
'undo/undo_manager_test.cc',
],
- # Note: GN tests converted to here, need to do the rest.
'audio_modem_unittest_sources': [
'audio_modem/audio_player_unittest.cc',
'audio_modem/audio_recorder_unittest.cc',
@@ -206,6 +219,9 @@
'cronet_unittest_sources': [
'cronet/histogram_manager_unittest.cc',
],
+ 'data_use_measurement_unittest_sources': [
+ 'data_use_measurement/content/data_use_measurement_unittest.cc',
+ ],
'enhanced_bookmarks_unittest_sources': [
'enhanced_bookmarks/enhanced_bookmark_model_unittest.cc',
'enhanced_bookmarks/image_store_ios_unittest.mm',
@@ -223,12 +239,18 @@
],
'gcm_driver_unittest_sources': [
'gcm_driver/gcm_account_mapper_unittest.cc',
+ 'gcm_driver/gcm_account_tracker_unittest.cc',
'gcm_driver/gcm_channel_status_request_unittest.cc',
'gcm_driver/gcm_client_impl_unittest.cc',
'gcm_driver/gcm_delayed_task_controller_unittest.cc',
'gcm_driver/gcm_driver_desktop_unittest.cc',
'gcm_driver/gcm_stats_recorder_impl_unittest.cc',
],
+ 'gcm_driver_crypto_unittest_sources': [
+ 'gcm_driver/crypto/encryption_header_parsers_unittest.cc',
+ 'gcm_driver/crypto/gcm_key_store_unittest.cc',
+ 'gcm_driver/crypto/gcm_message_cryptographer_unittest.cc',
+ ],
'google_unittest_sources': [
'google/core/browser/google_url_tracker_unittest.cc',
'google/core/browser/google_util_unittest.cc',
@@ -296,10 +318,17 @@
'login_unittest_sources': [
'login/screens/screen_context_unittest.cc',
],
+ 'memory_pressure_unittest_sources': [
+ 'memory_pressure/direct_memory_pressure_calculator_win_unittest.cc',
+ 'memory_pressure/filtered_memory_pressure_calculator_unittest.cc',
+ 'memory_pressure/memory_pressure_stats_collector_unittest.cc',
+ 'memory_pressure/test_memory_pressure_calculator.cc',
+ 'memory_pressure/test_memory_pressure_calculator.h',
+ ],
'metrics_unittest_sources': [
'metrics/call_stack_profile_metrics_provider_unittest.cc',
- 'metrics/compression_utils_unittest.cc',
'metrics/daily_event_unittest.cc',
+ 'metrics/drive_metrics_provider_unittest.cc',
'metrics/gpu/gpu_metrics_provider_unittest.cc',
'metrics/histogram_encoder_unittest.cc',
'metrics/machine_id_provider_win_unittest.cc',
@@ -313,6 +342,7 @@
'metrics/persisted_logs_unittest.cc',
'metrics/profiler/profiler_metrics_provider_unittest.cc',
'metrics/profiler/tracking_synchronizer_unittest.cc',
+ 'metrics/stability_metrics_helper_unittest.cc',
],
'mime_util_unittest_sources': [
'mime_util/mime_util_unittest.cc',
@@ -327,7 +357,7 @@
'nacl/zygote/nacl_fork_delegate_linux_unittest.cc',
],
'navigation_interception_unittest_sources': [
- 'navigation_interception/intercept_navigation_resource_throttle_unittest.cc',
+ 'navigation_interception/intercept_navigation_throttle_unittest.cc',
],
'network_hints_unittest_sources': [
'network_hints/renderer/dns_prefetch_queue_unittest.cc',
@@ -337,6 +367,7 @@
'network_time/network_time_tracker_unittest.cc',
],
'offline_page_unittest_sources': [
+ 'offline_pages/offline_page_metadata_store_impl_unittest.cc',
'offline_pages/offline_page_model_unittest.cc',
],
'omnibox_unittest_sources': [
@@ -345,12 +376,18 @@
'omnibox/browser/autocomplete_match_unittest.cc',
'omnibox/browser/autocomplete_result_unittest.cc',
'omnibox/browser/base_search_provider_unittest.cc',
+ 'omnibox/browser/clipboard_url_provider_unittest.cc',
'omnibox/browser/in_memory_url_index_types_unittest.cc',
'omnibox/browser/keyword_provider_unittest.cc',
'omnibox/browser/omnibox_field_trial_unittest.cc',
+ 'omnibox/browser/omnibox_popup_model_unittest.cc',
+ 'omnibox/browser/omnibox_view_unittest.cc',
'omnibox/browser/scored_history_match_unittest.cc',
'omnibox/browser/suggestion_answer_unittest.cc',
],
+ 'open_from_clipboard_unittest_sources': [
+ 'open_from_clipboard/clipboard_recent_content_ios_unittest.mm',
+ ],
'os_crypt_unittest_sources': [
'os_crypt/ie7_password_win_unittest.cc',
'os_crypt/keychain_password_mac_unittest.mm',
@@ -363,6 +400,11 @@
'packed_ct_ev_whitelist/bit_stream_reader_unittest.cc',
'packed_ct_ev_whitelist/packed_ct_ev_whitelist_unittest.cc',
],
+ 'page_load_metrics_unittest_sources': [
+ 'page_load_metrics/browser/metrics_web_contents_observer_unittest.cc',
+ 'page_load_metrics/renderer/metrics_render_frame_observer_unittest.cc',
+ 'page_load_metrics/renderer/page_timing_metrics_sender_unittest.cc',
+ ],
'password_manager_unittest_sources': [
'password_manager/content/browser/credential_manager_dispatcher_unittest.cc',
'password_manager/core/browser/affiliated_match_helper_unittest.cc',
@@ -378,9 +420,14 @@
'password_manager/core/browser/import/csv_reader_unittest.cc',
'password_manager/core/browser/log_router_unittest.cc',
'password_manager/core/browser/login_database_unittest.cc',
+ 'password_manager/core/browser/mock_affiliated_match_helper.cc',
+ 'password_manager/core/browser/mock_affiliated_match_helper.h',
'password_manager/core/browser/password_autofill_manager_unittest.cc',
+ 'password_manager/core/browser/password_bubble_experiment_unittest.cc',
'password_manager/core/browser/password_form_manager_unittest.cc',
'password_manager/core/browser/password_generation_manager_unittest.cc',
+ 'password_manager/core/browser/password_manager_metrics_util_unittest.cc',
+ 'password_manager/core/browser/password_manager_settings_migration_experiment_unittest.cc',
'password_manager/core/browser/password_manager_unittest.cc',
'password_manager/core/browser/password_store_default_unittest.cc',
'password_manager/core/browser/password_store_unittest.cc',
@@ -388,12 +435,19 @@
'password_manager/core/browser/psl_matching_helper_unittest.cc',
'password_manager/core/browser/statistics_table_unittest.cc',
'password_manager/core/common/credential_manager_types_unittest.cc',
+ 'password_manager/sync/browser/password_sync_util_unittest.cc',
+ 'password_manager/sync/browser/sync_store_result_filter_unittest.cc',
+ 'password_manager/sync/browser/sync_username_test_base.cc',
+ 'password_manager/sync/browser/sync_username_test_base.h',
],
'policy_unittest_sources': [
+ 'policy/core/browser/android/android_combined_policy_provider_unittest.cc',
+ 'policy/core/browser/android/policy_converter_unittest.cc',
'policy/core/browser/autofill_policy_handler_unittest.cc',
'policy/core/browser/browser_policy_connector_unittest.cc',
'policy/core/browser/configuration_policy_handler_unittest.cc',
'policy/core/browser/configuration_policy_pref_store_unittest.cc',
+ 'policy/core/browser/url_blacklist_manager_unittest.cc',
'policy/core/browser/url_blacklist_policy_handler_unittest.cc',
'policy/core/common/async_policy_provider_unittest.cc',
'policy/core/common/cloud/cloud_policy_client_unittest.cc',
@@ -422,7 +476,6 @@
'policy/core/common/policy_loader_mac_unittest.cc',
'policy/core/common/policy_loader_win_unittest.cc',
'policy/core/common/policy_map_unittest.cc',
- 'policy/core/common/policy_provider_android_unittest.cc',
'policy/core/common/policy_service_impl_unittest.cc',
'policy/core/common/policy_statistics_collector_unittest.cc',
'policy/core/common/preg_parser_win_unittest.cc',
@@ -443,6 +496,15 @@
'precache/core/precache_fetcher_unittest.cc',
'precache/core/precache_url_table_unittest.cc',
],
+ 'user_prefs_unittest_sources': [
+ 'user_prefs/tracked/device_id_unittest.cc',
+ 'user_prefs/tracked/pref_hash_calculator_unittest.cc',
+ 'user_prefs/tracked/pref_hash_filter_unittest.cc',
+ 'user_prefs/tracked/pref_hash_store_impl_unittest.cc',
+ 'user_prefs/tracked/pref_service_hash_store_contents_unittest.cc',
+ 'user_prefs/tracked/segregated_pref_store_unittest.cc',
+ 'user_prefs/tracked/tracked_preferences_migration_unittest.cc',
+ ],
'proximity_auth_unittest_sources': [
'proximity_auth/ble/bluetooth_low_energy_characteristics_finder_unittest.cc',
'proximity_auth/ble/bluetooth_low_energy_connection_finder_unittest.cc',
@@ -452,7 +514,6 @@
'proximity_auth/bluetooth_connection_finder_unittest.cc',
'proximity_auth/bluetooth_connection_unittest.cc',
'proximity_auth/bluetooth_throttler_impl_unittest.cc',
- 'proximity_auth/client_impl_unittest.cc',
'proximity_auth/connection_unittest.cc',
'proximity_auth/cryptauth/base64url_unittest.cc',
'proximity_auth/cryptauth/cryptauth_access_token_fetcher_impl_unittest.cc',
@@ -461,16 +522,26 @@
'proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc',
'proximity_auth/cryptauth/cryptauth_enroller_impl_unittest.cc',
'proximity_auth/cryptauth/cryptauth_enrollment_manager_unittest.cc',
+ 'proximity_auth/cryptauth/cryptauth_gcm_manager_impl_unittest.cc',
'proximity_auth/cryptauth/fake_secure_message_delegate_unittest.cc',
'proximity_auth/cryptauth/sync_scheduler_impl_unittest.cc',
+ 'proximity_auth/device_to_device_operations_unittest.cc',
+ 'proximity_auth/device_to_device_operations_unittest.cc',
+ 'proximity_auth/device_to_device_secure_context_unittest.cc',
'proximity_auth/logging/logging_unittest.cc',
+ 'proximity_auth/messenger_impl_unittest.cc',
+ 'proximity_auth/proximity_auth_pref_manager_unittest.cc',
'proximity_auth/proximity_auth_system_unittest.cc',
'proximity_auth/proximity_monitor_impl_unittest.cc',
+ 'proximity_auth/remote_device_life_cycle_impl_unittest.cc',
+ 'proximity_auth/remote_device_loader_unittest.cc',
'proximity_auth/remote_status_update_unittest.cc',
'proximity_auth/throttled_bluetooth_connection_finder_unittest.cc',
+ 'proximity_auth/unlock_manager_unittest.cc',
'proximity_auth/wire_message_unittest.cc',
],
'proxy_config_unittest_sources': [
+ 'proxy_config/pref_proxy_config_tracker_impl_unittest.cc',
'proxy_config/proxy_config_dictionary_unittest.cc',
'proxy_config/proxy_prefs_unittest.cc',
],
@@ -488,22 +559,34 @@
'rappor/rappor_utils_unittest.cc',
'rappor/sampler_unittest.cc',
],
+ 'rlz_unittest_sources': [
+ 'rlz/rlz_tracker_unittest.cc',
+ ],
+ 'safe_json_unittest_sources': [
+ 'safe_json/json_sanitizer_unittest.cc',
+ ],
'scheduler_unittest_sources': [
+ 'scheduler/base/nestable_task_runner_for_test.cc',
+ 'scheduler/base/nestable_task_runner_for_test.h',
+ 'scheduler/base/task_queue_manager_unittest.cc',
+ 'scheduler/base/task_queue_selector_unittest.cc',
+ 'scheduler/base/task_queue_sets_unittest.cc',
+ 'scheduler/base/test_always_fail_time_source.cc',
+ 'scheduler/base/test_always_fail_time_source.h',
+ 'scheduler/base/test_time_source.cc',
+ 'scheduler/base/test_time_source.h',
'scheduler/child/idle_helper_unittest.cc',
- 'scheduler/child/nestable_task_runner_for_test.cc',
- 'scheduler/child/nestable_task_runner_for_test.h',
- 'scheduler/child/prioritizing_task_queue_selector_unittest.cc',
'scheduler/child/scheduler_helper_unittest.cc',
- 'scheduler/child/task_queue_manager_unittest.cc',
- 'scheduler/child/test_time_source.cc',
- 'scheduler/child/test_time_source.h',
+ 'scheduler/child/scheduler_task_runner_delegate_for_test.cc',
+ 'scheduler/child/scheduler_task_runner_delegate_for_test.h',
+ 'scheduler/child/scheduler_task_runner_delegate_impl_unittest.cc',
'scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc',
'scheduler/child/worker_scheduler_impl_unittest.cc',
'scheduler/renderer/deadline_task_runner_unittest.cc',
'scheduler/renderer/renderer_scheduler_impl_unittest.cc',
+ 'scheduler/renderer/task_cost_estimator_unittest.cc',
+ 'scheduler/renderer/user_model_unittest.cc',
'scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc',
- 'scheduler/test/test_always_fail_time_source.cc',
- 'scheduler/test/test_always_fail_time_source.h',
],
'search_unittest_sources': [
'search/search_android_unittest.cc',
@@ -511,7 +594,6 @@
],
'search_engines_unittest_sources': [
'search_engines/default_search_manager_unittest.cc',
- 'search_engines/default_search_policy_handler_unittest.cc',
'search_engines/default_search_pref_migration_unittest.cc',
'search_engines/keyword_table_unittest.cc',
'search_engines/search_host_to_urls_map_unittest.cc',
@@ -526,11 +608,11 @@
'sessions_unittest_sources': [
'sessions/content/content_serialized_navigation_builder_unittest.cc',
'sessions/content/content_serialized_navigation_driver_unittest.cc',
+ 'sessions/core/serialized_navigation_entry_unittest.cc',
+ 'sessions/core/session_backend_unittest.cc',
+ 'sessions/core/session_types_unittest.cc',
'sessions/ios/ios_serialized_navigation_builder_unittest.cc',
'sessions/ios/ios_serialized_navigation_driver_unittest.cc',
- 'sessions/serialized_navigation_entry_unittest.cc',
- 'sessions/session_backend_unittest.cc',
- 'sessions/session_types_unittest.cc',
],
'signin_unittest_sources': [
'signin/core/browser/account_tracker_service_unittest.cc',
@@ -538,6 +620,7 @@
'signin/core/browser/refresh_token_annotation_request_unittest.cc',
'signin/core/browser/signin_error_controller_unittest.cc',
'signin/core/browser/webdata/token_service_table_unittest.cc',
+ 'signin/ios/browser/account_consistency_service_unittest.mm',
'signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm',
],
'storage_monitor_unittest_sources': [
@@ -558,18 +641,34 @@
'suggestions/suggestions_store_unittest.cc',
],
'sync_driver_unittest_sources': [
+ 'sync_driver/about_sync_util_unittest.cc',
+ 'sync_driver/backup_rollback_controller_unittest.cc',
'sync_driver/data_type_manager_impl_unittest.cc',
'sync_driver/device_info_data_type_controller_unittest.cc',
'sync_driver/device_info_sync_service_unittest.cc',
+ 'sync_driver/favicon_cache_unittest.cc',
'sync_driver/generic_change_processor_unittest.cc',
'sync_driver/model_association_manager_unittest.cc',
'sync_driver/non_blocking_data_type_controller_unittest.cc',
'sync_driver/non_ui_data_type_controller_unittest.cc',
+ 'sync_driver/revisit/current_tab_matcher_unittest.cc',
+ 'sync_driver/revisit/offset_tab_matcher_unittest.cc',
+ 'sync_driver/revisit/sessions_page_revisit_observer_unittest.cc',
'sync_driver/shared_change_processor_unittest.cc',
'sync_driver/sync_prefs_unittest.cc',
+ 'sync_driver/sync_stopped_reporter_unittest.cc',
+ 'sync_driver/sync_util_unittest.cc',
'sync_driver/system_encryptor_unittest.cc',
+ 'sync_driver/tab_node_pool_unittest.cc',
'sync_driver/ui_data_type_controller_unittest.cc',
],
+ 'syncable_prefs_unittest_sources': [
+ 'syncable_prefs/pref_model_associator_unittest.cc',
+ 'syncable_prefs/pref_service_syncable_unittest.cc',
+ ],
+ 'tracing_unittest_sources': [
+ 'tracing/trace_config_file_unittest.cc',
+ ],
'translate_unittest_sources': [
'translate/core/browser/language_state_unittest.cc',
'translate/core/browser/translate_browser_metrics_unittest.cc',
@@ -579,6 +678,7 @@
'translate/core/common/translate_metrics_unittest.cc',
'translate/core/common/translate_util_unittest.cc',
'translate/core/language_detection/language_detection_util_unittest.cc',
+ # TODO(GYP) bug 523060: these translate tests on iOS.
'translate/ios/browser/js_translate_manager_unittest.mm',
'translate/ios/browser/language_detection_controller_unittest.mm',
'translate/ios/browser/translate_controller_unittest.mm',
@@ -596,8 +696,13 @@
'update_client/update_query_params_unittest.cc',
'update_client/update_response_unittest.cc',
],
- 'url_fixer_unittest_sources': [
- 'url_fixer/url_fixer_unittest.cc',
+ 'upload_list_unittest_sources': [
+ 'upload_list/upload_list_unittest.cc',
+ ],
+ 'url_formatter_unittest_sources': [
+ 'url_formatter/elide_url_unittest.cc',
+ 'url_formatter/url_fixer_unittest.cc',
+ 'url_formatter/url_formatter_unittest.cc',
],
'url_matcher_unittest_sources': [
'url_matcher/regex_set_matcher_unittest.cc',
@@ -610,12 +715,17 @@
'variations/active_field_trials_unittest.cc',
'variations/caching_permuted_entropy_provider_unittest.cc',
'variations/entropy_provider_unittest.cc',
+ 'variations/experiment_labels_unittest.cc',
'variations/metrics_util_unittest.cc',
'variations/net/variations_http_header_provider_unittest.cc',
+ 'variations/service/variations_service_unittest.cc',
'variations/study_filtering_unittest.cc',
'variations/variations_associated_data_unittest.cc',
+ 'variations/variations_request_scheduler_mobile_unittest.cc',
+ 'variations/variations_request_scheduler_unittest.cc',
'variations/variations_seed_processor_unittest.cc',
'variations/variations_seed_simulator_unittest.cc',
+ 'variations/variations_seed_store_unittest.cc',
],
'visitedlink_unittest_sources': [
'visitedlink/test/visitedlink_unittest.cc',
@@ -631,27 +741,32 @@
],
'web_resource_unittest_sources': [
'web_resource/eula_accepted_notifier_unittest.cc',
+ 'web_resource/promo_resource_service_mobile_ntp_unittest.cc',
+ 'web_resource/promo_resource_service_unittest.cc',
'web_resource/resource_request_allowed_notifier_unittest.cc',
],
'webcrypto_unittest_sources': [
- 'webcrypto/test/aes_cbc_unittest.cc',
- 'webcrypto/test/aes_ctr_unittest.cc',
- 'webcrypto/test/aes_gcm_unittest.cc',
- 'webcrypto/test/aes_kw_unittest.cc',
- 'webcrypto/test/ecdh_unittest.cc',
- 'webcrypto/test/ecdsa_unittest.cc',
- 'webcrypto/test/hmac_unittest.cc',
- 'webcrypto/test/rsa_oaep_unittest.cc',
- 'webcrypto/test/rsa_pss_unittest.cc',
- 'webcrypto/test/rsa_ssa_unittest.cc',
- 'webcrypto/test/sha_unittest.cc',
- 'webcrypto/test/status_unittest.cc',
- 'webcrypto/test/test_helpers.cc',
- 'webcrypto/test/test_helpers.h',
+ 'webcrypto/algorithms/aes_cbc_unittest.cc',
+ 'webcrypto/algorithms/aes_ctr_unittest.cc',
+ 'webcrypto/algorithms/aes_gcm_unittest.cc',
+ 'webcrypto/algorithms/aes_kw_unittest.cc',
+ 'webcrypto/algorithms/ecdh_unittest.cc',
+ 'webcrypto/algorithms/ecdsa_unittest.cc',
+ 'webcrypto/algorithms/hmac_unittest.cc',
+ 'webcrypto/algorithms/rsa_oaep_unittest.cc',
+ 'webcrypto/algorithms/rsa_pss_unittest.cc',
+ 'webcrypto/algorithms/rsa_ssa_unittest.cc',
+ 'webcrypto/algorithms/sha_unittest.cc',
+ 'webcrypto/algorithms/test_helpers.cc',
+ 'webcrypto/algorithms/test_helpers.h',
+ 'webcrypto/status_unittest.cc',
],
'webdata_unittest_sources': [
'webdata/common/web_database_migration_unittest.cc',
],
+ 'webusb_detector_unittest_sources': [
+ 'webusb/webusb_detector_unittest.cc',
+ ],
},
'targets': [
{
@@ -692,19 +807,24 @@
'<@(autofill_unittest_sources)',
'<@(bookmarks_unittest_sources)',
'<@(browser_watcher_unittest_sources)',
+ '<@(bubble_unittest_sources)',
'<@(captive_portal_unittest_sources)',
+ '<@(certificate_reporting_unittest_sources)',
'<@(cloud_devices_unittest_sources)',
'<@(component_updater_unittest_sources)',
+ '<@(compression_unittest_sources)',
'<@(content_settings_unittest_sources)',
'<@(crash_unittest_sources)',
'<@(crx_file_unittest_sources)',
'<@(data_reduction_proxy_unittest_sources)',
+ '<@(data_use_measurement_unittest_sources)',
'<@(device_event_log_unittest_sources)',
'<@(dom_distiller_unittest_sources)',
'<@(domain_reliability_unittest_sources)',
'<@(enhanced_bookmarks_unittest_sources)',
'<@(favicon_base_unittest_sources)',
'<@(favicon_unittest_sources)',
+ '<@(gcm_driver_crypto_unittest_sources)',
'<@(gcm_driver_unittest_sources)',
'<@(google_unittest_sources)',
'<@(history_unittest_sources)',
@@ -714,11 +834,13 @@
'<@(language_usage_metrics_unittest_sources)',
'<@(leveldb_proto_unittest_sources)',
'<@(login_unittest_sources)',
+ '<@(memory_pressure_unittest_sources)',
'<@(metrics_unittest_sources)',
'<@(mime_util_unittest_sources)',
'<@(network_time_unittest_sources)',
'<@(offline_page_unittest_sources)',
'<@(omnibox_unittest_sources)',
+ '<@(open_from_clipboard_unittest_sources)',
'<@(os_crypt_unittest_sources)',
'<@(packed_ct_ev_whitelist_unittest_sources)',
'<@(password_manager_unittest_sources)',
@@ -726,22 +848,26 @@
'<@(proxy_config_unittest_sources)',
'<@(query_parser_unittest_sources)',
'<@(rappor_unittest_sources)',
- '<@(search_unittest_sources)',
'<@(search_engines_unittest_sources)',
'<@(search_provider_logos_unittest_sources)',
+ '<@(search_unittest_sources)',
'<@(sessions_unittest_sources)',
'<@(signin_unittest_sources)',
'<@(suggestions_unittest_sources)',
'<@(sync_driver_unittest_sources)',
+ '<@(syncable_prefs_unittest_sources)',
'<@(translate_unittest_sources)',
'<@(undo_unittest_sources)',
'<@(update_client_unittest_sources)',
- '<@(url_fixer_unittest_sources)',
+ '<@(upload_list_unittest_sources)',
+ '<@(url_formatter_unittest_sources)',
'<@(url_matcher_unittest_sources)',
+ '<@(user_prefs_unittest_sources)',
'<@(variations_unittest_sources)',
'<@(wallpaper_unittest_sources)',
'<@(web_resource_unittest_sources)',
'<@(webdata_unittest_sources)',
+ 'net_log/net_log_temp_file_unittest.cc',
],
'include_dirs': [
'..',
@@ -750,9 +876,6 @@
'../base/base.gyp:base',
'../base/base.gyp:base_prefs_test_support',
'../base/base.gyp:test_support_base',
- # TODO(blundell): Eliminate the need for this dependency in code
- # that iOS shares. crbug.com/325243
- '../content/content_shell_and_tests.gyp:test_support_content',
'../google_apis/google_apis.gyp:google_apis_test_support',
'../jingle/jingle.gyp:notifier_test_util',
'../net/net.gyp:net_test_support',
@@ -761,6 +884,7 @@
'../sync/sync.gyp:test_support_sync_api',
'../testing/gmock.gyp:gmock',
'../testing/gtest.gyp:gtest',
+ '../third_party/icu/icu.gyp:icui18n',
'../third_party/leveldatabase/leveldatabase.gyp:leveldatabase',
'../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_util',
'../third_party/libjingle/libjingle.gyp:libjingle',
@@ -781,17 +905,21 @@
'components.gyp:bookmarks_browser',
'components.gyp:bookmarks_managed',
'components.gyp:bookmarks_test_support',
+ 'components.gyp:bubble',
'components.gyp:captive_portal_test_support',
+ 'components.gyp:certificate_reporting',
'components.gyp:cloud_devices_common',
'components.gyp:component_updater',
+ 'components.gyp:compression',
'components.gyp:content_settings_core_browser',
'components.gyp:content_settings_core_common',
'components.gyp:content_settings_core_test_support',
- 'components.gyp:crash_test_support',
+ 'components.gyp:crash_core_common',
'components.gyp:crx_file',
'components.gyp:data_reduction_proxy_core_browser',
'components.gyp:data_reduction_proxy_core_common',
'components.gyp:data_reduction_proxy_test_support',
+ 'components.gyp:data_use_measurement_core',
'components.gyp:device_event_log_component',
'components.gyp:dom_distiller_core',
'components.gyp:dom_distiller_protos',
@@ -816,20 +944,22 @@
'components.gyp:leveldb_proto',
'components.gyp:leveldb_proto_test_support',
'components.gyp:login',
+ 'components.gyp:memory_pressure',
'components.gyp:metrics',
- 'components.gyp:metrics_gpu',
'components.gyp:metrics_net',
- 'components.gyp:metrics_profiler',
'components.gyp:metrics_test_support',
+ 'components.gyp:net_log',
'components.gyp:network_time',
'components.gyp:offline_pages',
'components.gyp:omnibox_browser',
'components.gyp:omnibox_test_support',
+ 'components.gyp:open_from_clipboard',
+ 'components.gyp:open_from_clipboard_test_support',
'components.gyp:os_crypt',
'components.gyp:packed_ct_ev_whitelist',
'components.gyp:password_manager_core_browser',
- 'components.gyp:password_manager_core_browser',
'components.gyp:password_manager_core_browser_test_support',
+ 'components.gyp:password_manager_sync_browser',
'components.gyp:precache_core',
'components.gyp:pref_registry_test_support',
'components.gyp:proxy_config',
@@ -845,6 +975,7 @@
'components.gyp:signin_core_browser_test_support',
'components.gyp:suggestions',
'components.gyp:sync_driver_test_support',
+ 'components.gyp:syncable_prefs_test_support',
'components.gyp:translate_core_browser',
'components.gyp:translate_core_common',
'components.gyp:translate_core_language_detection',
@@ -852,9 +983,14 @@
'components.gyp:undo_component',
'components.gyp:update_client',
'components.gyp:update_client_test_support',
- 'components.gyp:url_fixer',
+ 'components.gyp:upload_list',
+ 'components.gyp:url_matcher',
+ 'components.gyp:user_prefs_tracked',
+ 'components.gyp:user_prefs_tracked_test_support',
'components.gyp:variations',
'components.gyp:variations_http_provider',
+ 'components.gyp:variations_service',
+ 'components.gyp:version_info',
'components.gyp:wallpaper',
'components.gyp:web_resource',
'components.gyp:web_resource_test_support',
@@ -862,8 +998,31 @@
'components_strings.gyp:components_strings',
'components_tests_pak',
'mime_util/mime_util.gyp:mime_util',
+ 'url_formatter/url_formatter.gyp:url_formatter',
],
'conditions': [
+ ['OS!="mac" and OS!="ios"', {
+ 'sources!': [
+ 'crash/core/common/objc_zombie_unittest.mm',
+ ],
+ }],
+ ['enable_rlz_support==1', {
+ 'sources': [
+ '<@(rlz_unittest_sources)',
+ ],
+ 'dependencies': [
+ '../net/net.gyp:net_test_support',
+ '../rlz/rlz.gyp:test_support_rlz',
+ 'components.gyp:rlz',
+ ],
+ 'conditions': [
+ ['OS == "ios"', {
+ 'dependencies': [
+ '../ui/base/ui_base.gyp:ui_base',
+ ],
+ }],
+ ],
+ }],
['toolkit_views == 1', {
'sources': [
'bookmarks/browser/bookmark_node_data_unittest.cc',
@@ -886,19 +1045,22 @@
'<(DEPTH)/base/allocator/allocator.gyp:allocator',
],
}],
- [ 'cld_version==0 or cld_version==2', {
+ [ 'cld_version==2', {
'dependencies': [
# Unit tests should always use statically-linked CLD data.
'<(DEPTH)/third_party/cld_2/cld_2.gyp:cld2_static', ],
}],
['OS != "ios"', {
'sources': [
+ '<@(certificate_transparency_unittest_sources)',
'<@(devtools_http_handler_unittest_sources)',
'<@(error_page_unittest_sources)',
'<@(guest_view_unittest_sources)',
'<@(navigation_interception_unittest_sources)',
'<@(network_hints_unittest_sources)',
+ '<@(page_load_metrics_unittest_sources)',
'<@(power_unittest_sources)',
+ '<@(safe_json_unittest_sources)',
'<@(scheduler_unittest_sources)',
'<@(storage_monitor_unittest_sources)',
'<@(ui_unittest_sources)',
@@ -908,13 +1070,18 @@
'<@(web_modal_unittest_sources)',
],
'dependencies': [
+ '../content/content_shell_and_tests.gyp:test_support_content',
'../skia/skia.gyp:skia',
'components.gyp:autofill_content_browser',
'components.gyp:autofill_content_renderer',
'components.gyp:autofill_content_test_support',
+ 'components.gyp:certificate_transparency',
+ 'components.gyp:crash_test_support',
'components.gyp:data_reduction_proxy_content_browser',
+ 'components.gyp:data_use_measurement_content',
'components.gyp:devtools_http_handler',
- 'components.gyp:dom_distiller_content',
+ 'components.gyp:dom_distiller_content_browser',
+ 'components.gyp:dom_distiller_content_renderer',
'components.gyp:error_page_renderer',
'components.gyp:favicon_content',
'components.gyp:guest_view_browser',
@@ -924,10 +1091,16 @@
'components.gyp:keyed_service_content',
'components.gyp:navigation_interception',
'components.gyp:network_hints_renderer',
+ 'components.gyp:metrics_gpu',
+ 'components.gyp:metrics_profiler',
+ 'components.gyp:page_load_metrics_browser',
+ 'components.gyp:page_load_metrics_renderer',
'components.gyp:password_manager_content_browser',
'components.gyp:password_manager_content_common',
'components.gyp:power',
'components.gyp:precache_content',
+ 'components.gyp:safe_json',
+ 'components.gyp:safe_json_test_support',
'components.gyp:sessions_content',
'components.gyp:storage_monitor',
'components.gyp:storage_monitor_test_support',
@@ -938,6 +1111,7 @@
'components.gyp:web_modal',
'components.gyp:web_modal_test_support',
'scheduler/scheduler.gyp:scheduler',
+ 'test_runner/test_runner.gyp:test_runner',
'webcrypto/webcrypto.gyp:webcrypto',
'../third_party/re2/re2.gyp:re2',
],
@@ -947,6 +1121,11 @@
'../build/android/ndk.gyp:cpu_features',
],
}],
+ ['OS=="android" and configuration_policy == 1', {
+ 'dependencies': [
+ 'components.gyp:policy_java',
+ ],
+ }],
['use_openssl==1', {
'dependencies': [
'../third_party/boringssl/boringssl.gyp:boringssl',
@@ -968,12 +1147,13 @@
],
}, { # 'OS == "ios"'
'sources': [
- 'open_from_clipboard/clipboard_recent_content_ios_unittest.mm',
'webp_transcode/webp_decoder_unittest.mm',
'webp_transcode/webp_network_client_unittest.mm',
],
'sources!': [
'metrics/gpu/gpu_metrics_provider_unittest.cc',
+ 'metrics/profiler/profiler_metrics_provider_unittest.cc',
+ 'metrics/profiler/tracking_synchronizer_unittest.cc',
],
'sources/': [
# Exclude all tests that depends on //content (based on layered-
@@ -987,9 +1167,10 @@
'../ios/ios_tests.gyp:test_support_ios',
'../ios/web/ios_web.gyp:test_support_ios_web',
'../third_party/ocmock/ocmock.gyp:ocmock',
- 'components.gyp:open_from_clipboard',
+ 'components.gyp:autofill_ios_browser',
'components.gyp:sessions_ios',
'components.gyp:signin_ios_browser',
+ 'components.gyp:signin_ios_browser_test_support',
'components.gyp:translate_ios_browser',
'components.gyp:webp_transcode',
],
@@ -998,6 +1179,7 @@
'action_name': 'copy_test_data',
'variables': {
'test_data_files': [
+ '../net/data/ssl/certificates',
'test/data',
],
'test_data_prefix': 'components',
@@ -1051,7 +1233,7 @@
'gcm_driver/gcm_driver_desktop_unittest.cc',
'gcm_driver/gcm_stats_recorder_impl_unittest.cc',
'gcm_driver/instance_id/instance_id_driver_unittest.cc',
- 'sessions/session_backend_unittest.cc',
+ 'sessions/core/session_backend_unittest.cc',
'storage_monitor/media_storage_util_unittest.cc',
'storage_monitor/storage_info_unittest.cc',
'storage_monitor/storage_monitor_unittest.cc',
@@ -1060,6 +1242,7 @@
'dependencies': [
'components.gyp:cronet_static',
'components.gyp:data_reduction_proxy_content',
+ 'components.gyp:safe_json_java',
'../content/content.gyp:content_java',
'../testing/android/native_test.gyp:native_test_native_code',
],
@@ -1069,8 +1252,7 @@
'components.gyp:web_modal',
'components.gyp:web_modal_test_support',
],
- }],
- ['OS != "android"', {
+ }, {
'sources': [
'<@(invalidation_unittest_sources)',
],
@@ -1081,9 +1263,18 @@
'<@(copresence_unittest_sources)',
'<@(feedback_unittest_sources)',
'<@(proximity_auth_unittest_sources)',
+ '<@(tracing_unittest_sources)',
+ '<@(webusb_detector_unittest_sources)',
+ ],
+ 'sources!': [
+ 'variations/variations_request_scheduler_mobile_unittest.cc',
+ 'web_resource/promo_resource_service_mobile_ntp_unittest.cc',
],
'dependencies': [
'../device/bluetooth/bluetooth.gyp:device_bluetooth_mocks',
+ '../device/core/core.gyp:device_core',
+ '../device/usb/usb.gyp:device_usb',
+ '../device/usb/usb.gyp:device_usb_mocks',
'../google_apis/google_apis.gyp:google_apis_test_support',
'../third_party/protobuf/protobuf.gyp:protobuf_lite',
'components.gyp:audio_modem',
@@ -1091,9 +1282,14 @@
'components.gyp:copresence',
'components.gyp:copresence_test_support',
'components.gyp:cryptauth',
+ 'components.gyp:cryptauth_proto',
'components.gyp:cryptauth_test_support',
'components.gyp:feedback_component',
+ 'components.gyp:pref_registry_test_support',
'components.gyp:proximity_auth',
+ 'components.gyp:proximity_auth_test_support',
+ 'components.gyp:webusb',
+ 'tracing.gyp:tracing',
],
}],
['chromeos==1', {
@@ -1159,6 +1355,7 @@
'sources': [
'<@(policy_unittest_sources)',
'search_engines/default_search_policy_handler_unittest.cc',
+ 'sync_driver/sync_policy_handler_unittest.cc',
],
'conditions': [
['OS=="android"', {
@@ -1197,6 +1394,12 @@
}],
],
}],
+ ['enable_plugins == 1', {
+ 'sources': [
+ 'content_settings/core/browser/content_settings_provider_unittest.cc',
+ 'content_settings/core/browser/plugins_field_trial_unittest.cc',
+ ],
+ }],
],
# TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
'msvs_disabled_warnings': [4267, ],
@@ -1285,6 +1488,45 @@
},
'includes': [ '../build/apk_browsertest.gypi' ],
},
+ {
+ 'target_name': 'components_unittests_apk',
+ 'isolate_file': 'components_unittests.isolate',
+ 'type': 'none',
+ 'dependencies': [
+ 'components_unittests',
+ 'components.gyp:invalidation_java',
+ 'components.gyp:signin_core_browser_java',
+ ],
+ 'variables': {
+ 'test_suite_name': 'components_unittests',
+ },
+ 'includes': [ '../build/apk_test.gypi' ],
+ },
+ {
+ 'target_name': 'components_junit_tests',
+ 'type': 'none',
+ 'dependencies': [
+ 'components.gyp:invalidation_java',
+ '../base/base.gyp:base_java',
+ '../base/base.gyp:base_java_test_support',
+ '../testing/android/junit/junit_test.gyp:junit_test_support',
+ ],
+ 'conditions': [
+ ['configuration_policy == 1', {
+ 'dependencies': [
+ 'components.gyp:policy_java',
+ ],
+ }],
+ ],
+ 'variables': {
+ 'main_class': 'org.chromium.testing.local.JunitTestMain',
+ 'src_paths': [
+ 'invalidation/impl/android/junit/',
+ 'policy/android/junit/'
+ ],
+ },
+ 'includes': [ '../build/host_jar.gypi' ],
+ },
],
}],
['OS != "ios"', {
@@ -1306,7 +1548,9 @@
'..',
],
'sources': [
- 'scheduler/child/task_queue_manager_perftest.cc',
+ 'scheduler/base/nestable_task_runner_for_test.cc',
+ 'scheduler/base/nestable_task_runner_for_test.h',
+ 'scheduler/base/task_queue_manager_perftest.cc',
'visitedlink/test/visitedlink_perftest.cc',
],
'conditions': [
@@ -1344,7 +1588,8 @@
'components.gyp:autofill_content_renderer',
'components.gyp:content_settings_core_browser',
'components.gyp:content_settings_core_common',
- 'components.gyp:dom_distiller_content',
+ 'components.gyp:dom_distiller_content_browser',
+ 'components.gyp:dom_distiller_content_renderer',
'components.gyp:dom_distiller_core',
'components.gyp:password_manager_content_renderer',
'components.gyp:pref_registry_test_support',
@@ -1359,11 +1604,12 @@
'HAS_OUT_OF_PROC_TEST_RUNNER',
],
'sources': [
+ # Note: test list duplicated in GN build.
'autofill/content/browser/risk/fingerprint_browsertest.cc',
'autofill/content/renderer/password_form_conversion_utils_browsertest.cc',
- 'dom_distiller/content/distillable_page_utils_browsertest.cc',
- 'dom_distiller/content/distiller_page_web_contents_browsertest.cc',
- 'dom_distiller/content/test/dom_distiller_js_browsertest.cc',
+ 'dom_distiller/content/browser/distillable_page_utils_browsertest.cc',
+ 'dom_distiller/content/browser/distiller_page_web_contents_browsertest.cc',
+ 'dom_distiller/content/browser/test/dom_distiller_js_browsertest.cc',
'password_manager/content/renderer/credential_manager_client_browsertest.cc',
],
'conditions': [
@@ -1392,14 +1638,6 @@
'sources': [
'../content/shell/app/resource.h',
'../content/shell/app/shell.rc',
- # TODO: It would be nice to have these pulled in
- # automatically from direct_dependent_settings in
- # their various targets (net.gyp:net_resources, etc.),
- # but that causes errors in other targets when
- # resulting .res files get referenced multiple times.
- '<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_resources.rc',
- '<(SHARED_INTERMEDIATE_DIR)/content/app/strings/content_strings_en-US.rc',
- '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.rc',
],
'dependencies': [
'<(DEPTH)/content/app/resources/content_resources.gyp:content_resources',
@@ -1491,22 +1729,5 @@
},
],
}],
- ['OS == "android"', {
- 'targets': [
- {
- 'target_name': 'components_unittests_apk',
- 'isolate_file': 'components_unittests.isolate',
- 'type': 'none',
- 'dependencies': [
- 'components_unittests',
- 'components.gyp:invalidation_java',
- ],
- 'variables': {
- 'test_suite_name': 'components_unittests',
- },
- 'includes': [ '../build/apk_test.gypi' ],
- },
- ],
- }],
],
}
diff --git a/chromium/components/components_unittests.isolate b/chromium/components/components_unittests.isolate
index ccdaf162aea..4befb23f286 100644
--- a/chromium/components/components_unittests.isolate
+++ b/chromium/components/components_unittests.isolate
@@ -37,6 +37,7 @@
['OS=="android" or OS=="linux" or OS=="mac" or OS=="win"', {
'variables': {
'files': [
+ '../net/data/',
'test/data/',
'<(PRODUCT_DIR)/components_tests_resources.pak',
'<(PRODUCT_DIR)/ui_test.pak',
@@ -47,7 +48,6 @@
'variables': {
'files': [
'../testing/test_env.py',
- '<(PRODUCT_DIR)/components_unittests<(EXECUTABLE_SUFFIX)',
],
},
}],
@@ -91,6 +91,6 @@
],
'includes': [
'../base/base.isolate',
- '../third_party/angle/angle.isolate',
+ '../ui/gl/gl.isolate',
],
}
diff --git a/chromium/components/compression.gypi b/chromium/components/compression.gypi
new file mode 100644
index 00000000000..4c989717c41
--- /dev/null
+++ b/chromium/components/compression.gypi
@@ -0,0 +1,24 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/compression
+ 'target_name': 'compression',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../third_party/zlib/zlib.gyp:zlib',
+ ],
+ 'sources': [
+ 'compression/compression_utils.cc',
+ 'compression/compression_utils.h',
+ ],
+ },
+ ],
+}
diff --git a/chromium/components/content_settings.gypi b/chromium/components/content_settings.gypi
index 5fcbe000bac..f6ac047c4ff 100644
--- a/chromium/components/content_settings.gypi
+++ b/chromium/components/content_settings.gypi
@@ -14,8 +14,8 @@
'../net/net.gyp:net',
'../url/url.gyp:url_lib',
'content_settings_core_common',
- 'plugins_common',
'pref_registry',
+ 'url_formatter/url_formatter.gyp:url_formatter',
],
'variables': { 'enable_wexit_time_destructors': 1, },
'include_dirs': [
@@ -30,13 +30,13 @@
'content_settings/core/browser/content_settings_default_provider.h',
'content_settings/core/browser/content_settings_details.cc',
'content_settings/core/browser/content_settings_details.h',
+ 'content_settings/core/browser/content_settings_info.cc',
+ 'content_settings/core/browser/content_settings_info.h',
'content_settings/core/browser/content_settings_observable_provider.cc',
'content_settings/core/browser/content_settings_observable_provider.h',
'content_settings/core/browser/content_settings_observer.h',
'content_settings/core/browser/content_settings_origin_identifier_value_map.cc',
'content_settings/core/browser/content_settings_origin_identifier_value_map.h',
- 'content_settings/core/browser/content_settings_override_provider.cc',
- 'content_settings/core/browser/content_settings_override_provider.h',
'content_settings/core/browser/content_settings_policy_provider.cc',
'content_settings/core/browser/content_settings_policy_provider.h',
'content_settings/core/browser/content_settings_pref.cc',
@@ -44,6 +44,8 @@
'content_settings/core/browser/content_settings_pref_provider.cc',
'content_settings/core/browser/content_settings_pref_provider.h',
'content_settings/core/browser/content_settings_provider.h',
+ 'content_settings/core/browser/content_settings_registry.cc',
+ 'content_settings/core/browser/content_settings_registry.h',
'content_settings/core/browser/content_settings_rule.cc',
'content_settings/core/browser/content_settings_rule.h',
'content_settings/core/browser/content_settings_usages_state.cc',
@@ -55,8 +57,21 @@
'content_settings/core/browser/host_content_settings_map.cc',
'content_settings/core/browser/host_content_settings_map.h',
'content_settings/core/browser/local_shared_objects_counter.h',
- 'content_settings/core/browser/plugins_field_trial.cc',
- 'content_settings/core/browser/plugins_field_trial.h',
+ 'content_settings/core/browser/website_settings_info.cc',
+ 'content_settings/core/browser/website_settings_info.h',
+ 'content_settings/core/browser/website_settings_registry.cc',
+ 'content_settings/core/browser/website_settings_registry.h',
+ ],
+ 'conditions': [
+ ['enable_plugins == 1', {
+ 'sources': [
+ 'content_settings/core/browser/plugins_field_trial.cc',
+ 'content_settings/core/browser/plugins_field_trial.h',
+ ],
+ 'dependencies': [
+ 'plugins_common',
+ ],
+ }],
],
# TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
'msvs_disabled_warnings': [4267, ],
diff --git a/chromium/components/crash.gypi b/chromium/components/crash.gypi
index 6ba24028c34..6acfdfc4dd4 100644
--- a/chromium/components/crash.gypi
+++ b/chromium/components/crash.gypi
@@ -5,266 +5,48 @@
{
'targets': [
{
- 'target_name': 'crash_component_lib',
+ # GN version: //components/crash/core/common
+ 'target_name': 'crash_core_common',
'type': 'static_library',
- 'sources': [
- 'crash/app/crash_keys_win.cc',
- 'crash/app/crash_keys_win.h',
- 'crash/app/crash_reporter_client.cc',
- 'crash/app/crash_reporter_client.h',
- ],
'include_dirs': [
'..',
- '../breakpad/src',
- ],
- },
- {
- # TODO(mark): https://crbug.com/466890: merge this target with
- # crash_component.
- #
- # This is a temporary base target that is depended on by both
- # crash_component and crash_component_breakpad_mac_to_be_deleted. It
- # provides everything common to both of those targets. For a short period,
- # there are two Mac crash component implementations. The new one uses a
- # Crashpad implementation and is used by Chrome. The old one uses a
- # Breakpad implementation and is used by content_shell. Consumers should
- # depend on the desired target. All three targets behave identically on
- # non-Mac. When content_shell and any other consumers are migrated to the
- # Crashpad implementation on Mac, crash_component will merge back into
- # this target, crash_component_non_mac, which will be renamed
- # crash_component. crash_component_breakpad_mac_to_be_deleted will be
- # deleted.
- #
- # While this situation exists:
- #
- # Do not depend on this target directly! Depend on
- # crash_component_breakpad_mac_to_be_deleted for old Breakpad behavior on
- # all platforms, or preferably, depend on crash_component to get Breakpad
- # everywhere except for Mac, where you will get Crashpad.
- 'target_name': 'crash_component_non_mac',
- 'variables': {
- 'conditions': [
- ['OS == "ios" or OS == "mac"', {
- # On IOS there are no files compiled into the library, and we
- # can't have libraries with zero objects.
- # For now, the same applies to Mac OS X, until this target merges
- # with crash_component.
- 'crash_component_target_type%': 'none',
- }, {
- 'crash_component_target_type%': 'static_library',
- }],
- ],
- },
- 'type': '<(crash_component_target_type)',
- 'sources': [
- 'crash/app/breakpad_linux.cc',
- 'crash/app/breakpad_linux.h',
- 'crash/app/breakpad_linux_impl.h',
- 'crash/app/breakpad_win.cc',
- 'crash/app/breakpad_win.h',
- 'crash/app/hard_error_handler_win.cc',
- 'crash/app/hard_error_handler_win.h',
],
'dependencies': [
- 'crash_component_lib',
+ # List of dependencies is intentionally very minimal. Please avoid
+ # adding extra dependencies without first checking with OWNERS.
'../base/base.gyp:base',
],
- 'defines': ['CRASH_IMPLEMENTATION'],
- 'conditions': [
- ['OS=="win"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:breakpad_handler',
- '../breakpad/breakpad.gyp:breakpad_sender',
- '../sandbox/sandbox.gyp:sandbox',
- ],
- }],
- ['os_posix == 1 and OS != "mac" and OS != "ios"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:breakpad_client',
- ],
- 'include_dirs': [
- '../breakpad/src',
- ],
- }],
- ],
- 'target_conditions': [
- # Need 'target_conditions' to override default filename_rules to include
- # the files on Android.
- ['OS=="android"', {
- 'sources/': [
- ['include', '^crash/app/breakpad_linux\\.cc$'],
- ],
- }],
- ],
- },
- {
- # Note: if you depend on this target, you need to either link in
- # content.gyp:content_common, or add
- # content/public/common/content_switches.cc to your sources.
- #
- # GN version: //components/crash/app
-
- # TODO(mark): https://crbug.com/466890: merge this target with
- # crash_component_non_mac.
- #
- # Most of this target is actually in its dependency,
- # crash_component_non_mac. See the comment in that target for an
- # explanation for the split. The split is temporary and the two targets
- # will be unified again soon.
- 'target_name': 'crash_component',
- 'variables': {
- 'conditions': [
- ['OS != "mac" ', {
- # There are no source files on any platform but Mac OS X.
- 'crash_component_target_type%': 'none',
- }, {
- 'crash_component_target_type%': 'static_library',
- }],
- ],
- },
- 'type': '<(crash_component_target_type)',
- 'sources': [
- 'crash/app/crashpad_mac.h',
- 'crash/app/crashpad_mac.mm',
- ],
- 'dependencies': [
- 'crash_component_non_mac',
- 'crash_component_lib',
- '../base/base.gyp:base',
- ],
- 'defines': ['CRASH_IMPLEMENTATION'],
- 'conditions': [
- ['OS=="mac"', {
- 'dependencies': [
- '../third_party/crashpad/crashpad/client/client.gyp:crashpad_client',
- ],
- }],
- ],
- },
- {
- # TODO(mark): https://crbug.com/466890: remove this target.
- #
- # This is a temporary target provided for Mac Breakpad users that have not
- # yet migrated to Crashpad (namely content_shell). This target will be
- # removed shortly and all consumers will be expected to use Crashpad as
- # the Mac crash-reporting client. See the comment in the
- # crash_component_non_mac target for more details.
- 'target_name': 'crash_component_breakpad_mac_to_be_deleted',
- 'variables': {
- 'conditions': [
- ['OS != "mac" ', {
- # There are no source files on any platform but Mac OS X.
- 'crash_component_target_type%': 'none',
- }, {
- 'crash_component_target_type%': 'static_library',
- }],
- ],
- },
- 'type': '<(crash_component_target_type)',
'sources': [
- 'crash/app/breakpad_mac.h',
- 'crash/app/breakpad_mac.mm',
- ],
- 'dependencies': [
- 'crash_component_non_mac',
- 'crash_component_lib',
+ 'crash/core/common/crash_keys.cc',
+ 'crash/core/common/crash_keys.h',
],
- 'defines': ['CRASH_IMPLEMENTATION'],
'conditions': [
- ['OS=="mac"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:breakpad',
- ],
- 'include_dirs': [
- '..',
+ ['OS=="mac" or OS=="ios"', {
+ 'sources': [
+ 'crash/core/common/objc_zombie.h',
+ 'crash/core/common/objc_zombie.mm',
],
}],
],
},
- {
- # GN version: //components/crash/app:test_support
- 'target_name': 'crash_test_support',
- 'type': 'none',
- 'dependencies': [
- 'crash_component_lib',
- ],
- 'direct_dependent_settings': {
- 'include_dirs' : [
- '../breakpad/src',
- ],
- }
- },
],
'conditions': [
- ['OS=="win"', {
- 'targets': [
- {
- # GN version: //components/crash/tools:crash_service
- 'target_name': 'breakpad_crash_service',
- 'type': 'static_library',
- 'dependencies': [
- '../base/base.gyp:base',
- '../breakpad/breakpad.gyp:breakpad_handler',
- '../breakpad/breakpad.gyp:breakpad_sender',
- ],
- 'sources': [
- 'crash/tools/crash_service.cc',
- 'crash/tools/crash_service.h',
- ],
- },
- ],
- }],
['OS=="win" and target_arch=="ia32"', {
'targets': [
{
- # Note: if you depend on this target, you need to either link in
- # content.gyp:content_common, or add
- # content/public/common/content_switches.cc to your sources.
- 'target_name': 'breakpad_win64',
+ 'target_name': 'crash_core_common_win64',
'type': 'static_library',
- 'sources': [
- 'crash/app/breakpad_linux.cc',
- 'crash/app/breakpad_linux.h',
- 'crash/app/breakpad_linux_impl.h',
- 'crash/app/breakpad_mac.h',
- 'crash/app/breakpad_mac.mm',
- 'crash/app/breakpad_win.cc',
- 'crash/app/breakpad_win.h',
- # TODO(siggi): test the x64 version too.
- 'crash/app/crash_keys_win.cc',
- 'crash/app/crash_keys_win.h',
- 'crash/app/crash_reporter_client.cc',
- 'crash/app/crash_reporter_client.h',
- 'crash/app/hard_error_handler_win.cc',
- 'crash/app/hard_error_handler_win.h',
- ],
- 'defines': [
- 'COMPILE_CONTENT_STATICALLY',
- 'CRASH_IMPLEMENTATION',
- ],
- 'dependencies': [
- '../base/base.gyp:base_win64',
- '../breakpad/breakpad.gyp:breakpad_handler_win64',
- '../breakpad/breakpad.gyp:breakpad_sender_win64',
- '../sandbox/sandbox.gyp:sandbox_win64',
+ 'include_dirs': [
+ '..',
],
- 'configurations': {
- 'Common_Base': {
- 'msvs_target_platform': 'x64',
- },
- },
- },
- {
- 'target_name': 'breakpad_crash_service_win64',
- 'type': 'static_library',
'dependencies': [
+ # List of dependencies is intentionally very minimal. Please avoid
+ # adding extra dependencies without first checking with OWNERS.
'../base/base.gyp:base_win64',
- '../breakpad/breakpad.gyp:breakpad_handler_win64',
- '../breakpad/breakpad.gyp:breakpad_sender_win64',
],
'sources': [
- 'crash/tools/crash_service.cc',
- 'crash/tools/crash_service.h',
+ 'crash/core/common/crash_keys.cc',
+ 'crash/core/common/crash_keys.h',
],
'configurations': {
'Common_Base': {
@@ -274,55 +56,329 @@
},
],
}],
- ['OS=="mac"', {
+ ['OS!="ios"', {
'targets': [
{
- 'target_name': 'breakpad_stubs',
+ 'target_name': 'crash_component_lib',
'type': 'static_library',
- 'dependencies': [
- '../base/base.gyp:base',
- ],
'sources': [
- 'crash/app/breakpad_mac.h',
- 'crash/app/breakpad_mac_stubs.mm',
- 'crash/app/crash_reporter_client.cc',
- 'crash/app/crash_reporter_client.h',
+ 'crash/content/app/crash_keys_win.cc',
+ 'crash/content/app/crash_keys_win.h',
+ 'crash/content/app/crash_reporter_client.cc',
+ 'crash/content/app/crash_reporter_client.h',
+ ],
+ 'include_dirs': [
+ '..',
+ '../breakpad/src',
],
},
- ],
- }],
- ['os_posix == 1 and OS != "mac" and OS != "ios"', {
- 'targets': [
{
- # GN version: //components/crash/browser
- 'target_name': 'breakpad_host',
- 'type': 'static_library',
+ # TODO(mark): https://crbug.com/466890: merge this target with
+ # crash_component.
+ #
+ # This is a temporary base target that is depended on by both
+ # crash_component and crash_component_breakpad_mac_to_be_deleted. It
+ # provides everything common to both of those targets. For a short period,
+ # there are two Mac crash component implementations. The new one uses a
+ # Crashpad implementation and is used by Chrome. The old one uses a
+ # Breakpad implementation and is used by content_shell. Consumers should
+ # depend on the desired target. All three targets behave identically on
+ # non-Mac. When content_shell and any other consumers are migrated to the
+ # Crashpad implementation on Mac, crash_component will merge back into
+ # this target, crash_component_non_mac, which will be renamed
+ # crash_component. crash_component_breakpad_mac_to_be_deleted will be
+ # deleted.
+ #
+ # While this situation exists:
+ #
+ # Do not depend on this target directly! Depend on
+ # crash_component_breakpad_mac_to_be_deleted for old Breakpad behavior on
+ # all platforms, or preferably, depend on crash_component to get Breakpad
+ # everywhere except for Mac, where you will get Crashpad.
+ 'target_name': 'crash_component_non_mac',
+ 'variables': {
+ 'conditions': [
+ ['OS == "ios" or OS == "mac"', {
+ # On IOS there are no files compiled into the library, and we
+ # can't have libraries with zero objects.
+ # For now, the same applies to Mac OS X, until this target merges
+ # with crash_component.
+ 'crash_component_target_type%': 'none',
+ }, {
+ 'crash_component_target_type%': 'static_library',
+ }],
+ ],
+ },
+ 'type': '<(crash_component_target_type)',
+ 'sources': [
+ 'crash/content/app/breakpad_linux.cc',
+ 'crash/content/app/breakpad_linux.h',
+ 'crash/content/app/breakpad_linux_impl.h',
+ 'crash/content/app/breakpad_win.cc',
+ 'crash/content/app/breakpad_win.h',
+ 'crash/content/app/hard_error_handler_win.cc',
+ 'crash/content/app/hard_error_handler_win.h',
+ ],
'dependencies': [
- 'crash_component',
+ 'crash_component_lib',
'../base/base.gyp:base',
- '../breakpad/breakpad.gyp:breakpad_client',
- '../content/content.gyp:content_browser',
- '../content/content.gyp:content_common',
- ],
- 'sources': [
- 'crash/browser/crash_dump_manager_android.cc',
- 'crash/browser/crash_dump_manager_android.h',
- 'crash/browser/crash_handler_host_linux.cc',
- 'crash/browser/crash_handler_host_linux.h',
],
- 'include_dirs': [
- '../breakpad/src',
+ 'defines': ['CRASH_IMPLEMENTATION'],
+ 'conditions': [
+ ['OS=="win"', {
+ 'dependencies': [
+ '../breakpad/breakpad.gyp:breakpad_handler',
+ '../breakpad/breakpad.gyp:breakpad_sender',
+ '../sandbox/sandbox.gyp:sandbox',
+ ],
+ }],
+ ['os_posix == 1 and OS != "mac" and OS != "ios"', {
+ 'dependencies': [
+ '../breakpad/breakpad.gyp:breakpad_client',
+ ],
+ 'include_dirs': [
+ '../breakpad/src',
+ ],
+ }],
],
'target_conditions': [
# Need 'target_conditions' to override default filename_rules to include
# the files on Android.
['OS=="android"', {
'sources/': [
- ['include', '^crash/browser/crash_handler_host_linux\\.cc$'],
+ ['include', '^crash/content/app/breakpad_linux\\.cc$'],
+ ],
+ }],
+ ],
+ },
+ {
+ # Note: if you depend on this target, you need to either link in
+ # content.gyp:content_common, or add
+ # content/public/common/content_switches.cc to your sources.
+ #
+ # GN version: //components/crash/content/app
+
+ # TODO(mark): https://crbug.com/466890: merge this target with
+ # crash_component_non_mac.
+ #
+ # Most of this target is actually in its dependency,
+ # crash_component_non_mac. See the comment in that target for an
+ # explanation for the split. The split is temporary and the two targets
+ # will be unified again soon.
+ 'target_name': 'crash_component',
+ 'variables': {
+ 'conditions': [
+ ['OS != "mac" ', {
+ # There are no source files on any platform but Mac OS X.
+ 'crash_component_target_type%': 'none',
+ }, {
+ 'crash_component_target_type%': 'static_library',
+ }],
+ ],
+ },
+ 'type': '<(crash_component_target_type)',
+ 'sources': [
+ 'crash/content/app/crashpad_mac.h',
+ 'crash/content/app/crashpad_mac.mm',
+ ],
+ 'dependencies': [
+ 'crash_component_non_mac',
+ 'crash_component_lib',
+ '../base/base.gyp:base',
+ ],
+ 'defines': ['CRASH_IMPLEMENTATION'],
+ 'conditions': [
+ ['OS=="mac"', {
+ 'dependencies': [
+ '../third_party/crashpad/crashpad/client/client.gyp:crashpad_client',
+ ],
+ }],
+ ],
+ },
+ {
+ # TODO(mark): https://crbug.com/466890: remove this target.
+ #
+ # This is a temporary target provided for Mac Breakpad users that have not
+ # yet migrated to Crashpad (namely content_shell). This target will be
+ # removed shortly and all consumers will be expected to use Crashpad as
+ # the Mac crash-reporting client. See the comment in the
+ # crash_component_non_mac target for more details.
+ 'target_name': 'crash_component_breakpad_mac_to_be_deleted',
+ 'variables': {
+ 'conditions': [
+ ['OS != "mac" ', {
+ # There are no source files on any platform but Mac OS X.
+ 'crash_component_target_type%': 'none',
+ }, {
+ 'crash_component_target_type%': 'static_library',
+ }],
+ ],
+ },
+ 'type': '<(crash_component_target_type)',
+ 'sources': [
+ 'crash/content/app/breakpad_mac.h',
+ 'crash/content/app/breakpad_mac.mm',
+ ],
+ 'dependencies': [
+ 'crash_component_non_mac',
+ 'crash_component_lib',
+ ],
+ 'defines': ['CRASH_IMPLEMENTATION'],
+ 'conditions': [
+ ['OS=="mac"', {
+ 'dependencies': [
+ '../breakpad/breakpad.gyp:breakpad',
+ ],
+ 'include_dirs': [
+ '..',
],
}],
],
},
+ {
+ # GN version: //components/crash/content/app:test_support
+ 'target_name': 'crash_test_support',
+ 'type': 'none',
+ 'dependencies': [
+ 'crash_component_lib',
+ ],
+ 'direct_dependent_settings': {
+ 'include_dirs' : [
+ '../breakpad/src',
+ ],
+ }
+ },
+ ],
+ 'conditions': [
+ ['OS=="win"', {
+ 'targets': [
+ {
+ # GN version: //components/crash/content/tools:crash_service
+ 'target_name': 'breakpad_crash_service',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../breakpad/breakpad.gyp:breakpad_handler',
+ '../breakpad/breakpad.gyp:breakpad_sender',
+ ],
+ 'sources': [
+ 'crash/content/tools/crash_service.cc',
+ 'crash/content/tools/crash_service.h',
+ ],
+ },
+ ],
+ }],
+ ['OS=="win" and target_arch=="ia32"', {
+ 'targets': [
+ {
+ # Note: if you depend on this target, you need to either link in
+ # content.gyp:content_common, or add
+ # content/public/common/content_switches.cc to your sources.
+ 'target_name': 'breakpad_win64',
+ 'type': 'static_library',
+ 'sources': [
+ 'crash/content/app/breakpad_linux.cc',
+ 'crash/content/app/breakpad_linux.h',
+ 'crash/content/app/breakpad_linux_impl.h',
+ 'crash/content/app/breakpad_mac.h',
+ 'crash/content/app/breakpad_mac.mm',
+ 'crash/content/app/breakpad_win.cc',
+ 'crash/content/app/breakpad_win.h',
+ # TODO(siggi): test the x64 version too.
+ 'crash/content/app/crash_keys_win.cc',
+ 'crash/content/app/crash_keys_win.h',
+ 'crash/content/app/crash_reporter_client.cc',
+ 'crash/content/app/crash_reporter_client.h',
+ 'crash/content/app/hard_error_handler_win.cc',
+ 'crash/content/app/hard_error_handler_win.h',
+ ],
+ 'defines': [
+ 'COMPILE_CONTENT_STATICALLY',
+ 'CRASH_IMPLEMENTATION',
+ ],
+ 'dependencies': [
+ '../base/base.gyp:base_win64',
+ '../breakpad/breakpad.gyp:breakpad_handler_win64',
+ '../breakpad/breakpad.gyp:breakpad_sender_win64',
+ '../sandbox/sandbox.gyp:sandbox_win64',
+ ],
+ 'configurations': {
+ 'Common_Base': {
+ 'msvs_target_platform': 'x64',
+ },
+ },
+ },
+ {
+ 'target_name': 'breakpad_crash_service_win64',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base_win64',
+ '../breakpad/breakpad.gyp:breakpad_handler_win64',
+ '../breakpad/breakpad.gyp:breakpad_sender_win64',
+ ],
+ 'sources': [
+ 'crash/content/tools/crash_service.cc',
+ 'crash/content/tools/crash_service.h',
+ ],
+ 'configurations': {
+ 'Common_Base': {
+ 'msvs_target_platform': 'x64',
+ },
+ },
+ },
+ ],
+ }],
+ ['OS=="mac"', {
+ 'targets': [
+ {
+ 'target_name': 'breakpad_stubs',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ ],
+ 'sources': [
+ 'crash/content/app/breakpad_mac.h',
+ 'crash/content/app/breakpad_mac_stubs.mm',
+ 'crash/content/app/crash_reporter_client.cc',
+ 'crash/content/app/crash_reporter_client.h',
+ ],
+ },
+ ],
+ }],
+ ['os_posix == 1 and OS != "mac"', {
+ 'targets': [
+ {
+ # GN version: //components/crash/content/browser
+ 'target_name': 'breakpad_host',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'crash_component',
+ '../base/base.gyp:base',
+ '../breakpad/breakpad.gyp:breakpad_client',
+ '../content/content.gyp:content_browser',
+ '../content/content.gyp:content_common',
+ ],
+ 'sources': [
+ 'crash/content/browser/crash_dump_manager_android.cc',
+ 'crash/content/browser/crash_dump_manager_android.h',
+ 'crash/content/browser/crash_handler_host_linux.cc',
+ 'crash/content/browser/crash_handler_host_linux.h',
+ ],
+ 'include_dirs': [
+ '../breakpad/src',
+ ],
+ 'target_conditions': [
+ # Need 'target_conditions' to override default filename_rules to include
+ # the files on Android.
+ ['OS=="android"', {
+ 'sources/': [
+ ['include', '^crash/content/browser/crash_handler_host_linux\\.cc$'],
+ ],
+ }],
+ ],
+ },
+ ],
+ }],
],
}],
],
diff --git a/chromium/components/cronet.gypi b/chromium/components/cronet.gypi
index 019e11968ed..5a63b94b892 100644
--- a/chromium/components/cronet.gypi
+++ b/chromium/components/cronet.gypi
@@ -41,6 +41,14 @@
'includes': [ '../build/android/java_cpp_enum.gypi' ],
},
{
+ 'target_name': 'network_quality_observations_java',
+ 'type': 'none',
+ 'variables': {
+ 'source_file': '../net/base/network_quality_estimator.h',
+ },
+ 'includes': [ '../build/android/java_cpp_enum.gypi' ],
+ },
+ {
'target_name': 'cronet_url_request_context_config_list',
'type': 'none',
'sources': [
@@ -149,6 +157,7 @@
# cronet_static_small target has reduced binary size through using
# ICU alternatives which requires file and ftp support be disabled.
'target_name': 'cronet_static_small',
+ 'type': 'static_library',
'defines': [
'USE_ICU_ALTERNATIVES_ON_ANDROID=1',
'DISABLE_FILE_SUPPORT=1',
@@ -157,7 +166,6 @@
'dependencies': [
'../net/net.gyp:net_small',
],
- 'includes': [ 'cronet/cronet_static.gypi' ],
'conditions': [
['enable_data_reduction_proxy_support==1',
{
@@ -167,15 +175,16 @@
},
],
],
+ 'includes': [ 'cronet/cronet_static.gypi' ],
},
{
# cronet_static target depends on ICU and includes file and ftp support.
'target_name': 'cronet_static',
+ 'type': 'static_library',
'dependencies': [
'../base/base.gyp:base_i18n',
'../net/net.gyp:net',
],
- 'includes': [ 'cronet/cronet_static.gypi' ],
'conditions': [
['enable_data_reduction_proxy_support==1',
{
@@ -185,6 +194,7 @@
},
],
],
+ 'includes': [ 'cronet/cronet_static.gypi' ],
},
{
'target_name': 'libcronet',
@@ -207,6 +217,7 @@
'cronet_url_request_context_config_list',
'cronet_version',
'load_states_list',
+ 'network_quality_observations_java',
],
'variables': {
'java_in_dir': 'cronet/android/java',
@@ -217,10 +228,10 @@
'**/HttpUrlConnection*.java',
'**/HttpUrlRequest*.java',
'**/LoadState.java',
- '**/RequestStatus.java',
+ '**/NetworkQualityRttListener.java',
+ '**/NetworkQualityThroughputListener.java',
'**/ResponseInfo.java',
'**/ResponseTooLargeException.java',
- '**/StatusListener.java',
'**/UploadDataProvider.java',
'**/UploadDataSink.java',
'**/UrlRequest.java',
@@ -245,6 +256,7 @@
'cronet_url_request_java',
'libcronet',
'net_request_priority_java',
+ 'network_quality_observations_java',
],
'variables': {
'java_in_dir': 'cronet/android/java',
@@ -321,7 +333,6 @@
'variables': {
'apk_name': 'CronetSampleTest',
'java_in_dir': 'cronet/android/sample/javatests',
- 'resource_dir': 'cronet/android/sample/res',
'is_test_apk': 1,
},
'includes': [ '../build/java_apk.gypi' ],
@@ -362,7 +373,6 @@
'cronet/android/test/network_change_notifier_util.h',
],
'dependencies': [
- 'cronet_static',
'cronet_tests_jni_headers',
'../base/base.gyp:base',
'../net/net.gyp:net',
@@ -374,15 +384,19 @@
'../third_party/icu/icu.gyp:icui18n',
'../third_party/icu/icu.gyp:icuuc',
],
- 'conditions' : [
+ 'defines': [
+ 'CRONET_TEST=1',
+ ],
+ 'conditions': [
['enable_data_reduction_proxy_support==1',
{
- 'defines' : [
- 'DATA_REDUCTION_PROXY_SUPPORT'
+ 'dependencies': [
+ '../components/components.gyp:data_reduction_proxy_core_browser',
],
},
],
],
+ 'includes': [ 'cronet/cronet_static.gypi' ],
},
{
'target_name': 'cronet_test_apk',
@@ -526,6 +540,9 @@
'action': [
'python',
'<@(_inputs)',
+ '--src-dir=../base/android/java/src',
+ '--src-dir=../net/android/java/src',
+ '--src-dir=../url/android/java/src',
'--src-dir=cronet/android/java/src',
'--jar-path=<(package_dir)/<(java_src_lib)',
],
@@ -559,9 +576,10 @@
'action': [
'python',
'<@(_inputs)',
- '--source-dir=src',
- '--output-dir=<(package_dir)/javadoc',
- '--working-dir=cronet/android/java',
+ '--output-dir=<(package_dir)',
+ '--input-dir=cronet/',
+ '--overview-file=<(package_dir)/README.md.html',
+ '--readme-file=cronet/README.md',
],
'message': 'Generating Javadoc',
},
diff --git a/chromium/components/cronet/cronet_static.gypi b/chromium/components/cronet/cronet_static.gypi
index 9ce059effcd..08601cef579 100644
--- a/chromium/components/cronet/cronet_static.gypi
+++ b/chromium/components/cronet/cronet_static.gypi
@@ -4,7 +4,6 @@
{
# This target is included into both 'cronet_static' and 'cronet_static_small'.
- 'type': 'static_library',
'dependencies': [
'../base/base.gyp:base',
'../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
@@ -77,7 +76,7 @@
'android/cronet_data_reduction_proxy.cc',
'android/cronet_data_reduction_proxy.h',
],
- }
- ],
+ }
+ ],
],
}
diff --git a/chromium/components/crx_file.gypi b/chromium/components/crx_file.gypi
index 036550d3959..fd9956357bc 100644
--- a/chromium/components/crx_file.gypi
+++ b/chromium/components/crx_file.gypi
@@ -9,6 +9,7 @@
'type': 'static_library',
'dependencies': [
'../base/base.gyp:base',
+ '../crypto/crypto.gyp:crypto',
],
'include_dirs': [
'..',
diff --git a/chromium/components/data_reduction_proxy.gypi b/chromium/components/data_reduction_proxy.gypi
index 931c9306448..ff704c3ce2b 100644
--- a/chromium/components/data_reduction_proxy.gypi
+++ b/chromium/components/data_reduction_proxy.gypi
@@ -207,6 +207,9 @@
'data_reduction_proxy_proto',
'../third_party/leveldatabase/leveldatabase.gyp:leveldatabase',
],
+ 'export_dependent_settings': [
+ 'data_reduction_proxy_proto',
+ ],
'include_dirs': [
'..',
],
@@ -245,6 +248,7 @@
'data_reduction_proxy_content',
'data_reduction_proxy_core_browser',
'data_reduction_proxy_core_common',
+ 'data_reduction_proxy_proto',
],
'include_dirs': [
'..',
diff --git a/chromium/components/data_use_measurement.gypi b/chromium/components/data_use_measurement.gypi
new file mode 100644
index 00000000000..7f80e4ef87b
--- /dev/null
+++ b/chromium/components/data_use_measurement.gypi
@@ -0,0 +1,33 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+{
+ 'targets': [
+ {
+ 'target_name': 'data_use_measurement_content',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../content/content.gyp:content_browser',
+ '../net/net.gyp:net',
+ 'data_use_measurement_core',
+ ],
+ 'sources': [
+ 'data_use_measurement/content/data_use_measurement.cc',
+ 'data_use_measurement/content/data_use_measurement.h',
+ ]
+ },
+ {
+ 'target_name': 'data_use_measurement_core',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../net/net.gyp:net',
+ ],
+ 'sources': [
+ 'data_use_measurement/core/data_use_user_data.cc',
+ 'data_use_measurement/core/data_use_user_data.h',
+ ]
+ }
+ ]
+}
diff --git a/chromium/components/device_event_log/device_event_log_impl.cc b/chromium/components/device_event_log/device_event_log_impl.cc
index 7b339b5539b..94ee5fded90 100644
--- a/chromium/components/device_event_log/device_event_log_impl.cc
+++ b/chromium/components/device_event_log/device_event_log_impl.cc
@@ -220,7 +220,7 @@ void GetFormat(const std::string& format_string,
}
LogType LogTypeFromString(const std::string& desc) {
- std::string desc_lc = base::StringToLowerASCII(desc);
+ std::string desc_lc = base::ToLowerASCII(desc);
if (desc_lc == "network")
return LOG_TYPE_NETWORK;
if (desc_lc == "power")
diff --git a/chromium/components/device_event_log/device_event_log_impl_unittest.cc b/chromium/components/device_event_log/device_event_log_impl_unittest.cc
index 706039d9c64..0154bd49201 100644
--- a/chromium/components/device_event_log/device_event_log_impl_unittest.cc
+++ b/chromium/components/device_event_log/device_event_log_impl_unittest.cc
@@ -53,14 +53,13 @@ class DeviceEventLogTest : public testing::Test {
protected:
std::string SkipTime(const std::string& input) {
std::string output;
- std::vector<std::string> lines;
- base::SplitString(input, '\n', &lines);
- for (size_t i = 0; i < lines.size(); ++i) {
- size_t n = lines[i].find(']');
+ for (const std::string& line : base::SplitString(
+ input, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
+ size_t n = line.find(']');
if (n != std::string::npos)
- output += "[time] " + lines[i].substr(n + 2) + '\n';
+ output += "[time] " + line.substr(n + 2) + '\n';
else
- output += lines[i];
+ output += line;
}
return output;
}
diff --git a/chromium/components/devtools_discovery/devtools_discovery_manager.cc b/chromium/components/devtools_discovery/devtools_discovery_manager.cc
index ff006bde8b1..752dec10c35 100644
--- a/chromium/components/devtools_discovery/devtools_discovery_manager.cc
+++ b/chromium/components/devtools_discovery/devtools_discovery_manager.cc
@@ -14,7 +14,7 @@ namespace devtools_discovery {
// static
DevToolsDiscoveryManager* DevToolsDiscoveryManager::GetInstance() {
- return Singleton<DevToolsDiscoveryManager>::get();
+ return base::Singleton<DevToolsDiscoveryManager>::get();
}
DevToolsDiscoveryManager::DevToolsDiscoveryManager() {
diff --git a/chromium/components/devtools_discovery/devtools_discovery_manager.h b/chromium/components/devtools_discovery/devtools_discovery_manager.h
index d4f0e85dd97..45f45d7ec2c 100644
--- a/chromium/components/devtools_discovery/devtools_discovery_manager.h
+++ b/chromium/components/devtools_discovery/devtools_discovery_manager.h
@@ -38,7 +38,7 @@ class DevToolsDiscoveryManager {
scoped_ptr<DevToolsTargetDescriptor> CreateNew(const GURL& url);
private:
- friend struct DefaultSingletonTraits<DevToolsDiscoveryManager>;
+ friend struct base::DefaultSingletonTraits<DevToolsDiscoveryManager>;
DevToolsDiscoveryManager();
~DevToolsDiscoveryManager();
diff --git a/chromium/components/devtools_http_handler/BUILD.gn b/chromium/components/devtools_http_handler/BUILD.gn
index e37cb3506f0..d442152979c 100644
--- a/chromium/components/devtools_http_handler/BUILD.gn
+++ b/chromium/components/devtools_http_handler/BUILD.gn
@@ -26,6 +26,7 @@ source_set("unit_tests") {
deps = [
":devtools_http_handler",
+ "//content/test:test_support",
"//testing/gtest",
]
}
diff --git a/chromium/components/devtools_http_handler/devtools_http_handler.cc b/chromium/components/devtools_http_handler/devtools_http_handler.cc
index 16e7d04cf29..e4af63d474d 100644
--- a/chromium/components/devtools_http_handler/devtools_http_handler.cc
+++ b/chromium/components/devtools_http_handler/devtools_http_handler.cc
@@ -23,6 +23,7 @@
#include "components/devtools_http_handler/devtools_http_handler_delegate.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_agent_host.h"
+#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/user_agent.h"
#include "net/base/escape.h"
@@ -98,7 +99,7 @@ class ServerWrapper : net::HttpServer::Delegate {
void WriteActivePortToUserProfile(const base::FilePath& output_directory);
- virtual ~ServerWrapper() {}
+ ~ServerWrapper() override {}
private:
// net::HttpServer::Delegate implementation.
@@ -359,17 +360,22 @@ static std::string PathWithoutParams(const std::string& path) {
}
static std::string GetMimeType(const std::string& filename) {
- if (base::EndsWith(filename, ".html", false)) {
+ if (base::EndsWith(filename, ".html", base::CompareCase::INSENSITIVE_ASCII)) {
return "text/html";
- } else if (base::EndsWith(filename, ".css", false)) {
+ } else if (base::EndsWith(filename, ".css",
+ base::CompareCase::INSENSITIVE_ASCII)) {
return "text/css";
- } else if (base::EndsWith(filename, ".js", false)) {
+ } else if (base::EndsWith(filename, ".js",
+ base::CompareCase::INSENSITIVE_ASCII)) {
return "application/javascript";
- } else if (base::EndsWith(filename, ".png", false)) {
+ } else if (base::EndsWith(filename, ".png",
+ base::CompareCase::INSENSITIVE_ASCII)) {
return "image/png";
- } else if (base::EndsWith(filename, ".gif", false)) {
+ } else if (base::EndsWith(filename, ".gif",
+ base::CompareCase::INSENSITIVE_ASCII)) {
return "image/gif";
- } else if (base::EndsWith(filename, ".json", false)) {
+ } else if (base::EndsWith(filename, ".json",
+ base::CompareCase::INSENSITIVE_ASCII)) {
return "application/json";
}
LOG(ERROR) << "GetMimeType doesn't know mime type for: "
@@ -696,6 +702,18 @@ void DevToolsHttpHandler::OnWebSocketRequest(
return;
}
+ // Handle external connections (such as frontend api) on the embedder level.
+ content::DevToolsExternalAgentProxyDelegate* external_delegate =
+ delegate_->HandleWebSocketConnection(request.path);
+ if (external_delegate) {
+ scoped_refptr<DevToolsAgentHost> agent_host =
+ DevToolsAgentHost::Create(external_delegate);
+ connection_to_client_[connection_id] = new DevToolsAgentHostClientImpl(
+ thread_->message_loop(), server_wrapper_, connection_id, agent_host);
+ AcceptWebSocket(connection_id, request);
+ return;
+ }
+
size_t pos = request.path.find(kPageUrlPrefix);
if (pos != 0) {
Send404(connection_id);
@@ -796,7 +814,7 @@ void ServerWrapper::WriteActivePortToUserProfile(
// Write this port to a well-known file in the profile directory
// so Telemetry can pick it up.
base::FilePath path = output_directory.Append(kDevToolsActivePortFileName);
- std::string port_string = base::IntToString(endpoint.port());
+ std::string port_string = base::UintToString(endpoint.port());
if (base::WriteFile(path, port_string.c_str(),
static_cast<int>(port_string.length())) < 0) {
LOG(ERROR) << "Error writing DevTools active port to file";
diff --git a/chromium/components/devtools_http_handler/devtools_http_handler_delegate.h b/chromium/components/devtools_http_handler/devtools_http_handler_delegate.h
index 8a45ca1141a..cf4b9db7c74 100644
--- a/chromium/components/devtools_http_handler/devtools_http_handler_delegate.h
+++ b/chromium/components/devtools_http_handler/devtools_http_handler_delegate.h
@@ -9,6 +9,10 @@
#include "url/gurl.h"
+namespace content {
+class DevToolsExternalAgentProxyDelegate;
+}
+
namespace devtools_http_handler {
class DevToolsHttpHandlerDelegate {
@@ -26,6 +30,11 @@ class DevToolsHttpHandlerDelegate {
// Get a thumbnail for a given page. Returns non-empty string iff we have the
// thumbnail.
virtual std::string GetPageThumbnailData(const GURL& url) = 0;
+
+ // Allows embedder to handle custom websocket-based protocol connection
+ // pointing remote debugging port. Returns ownership.
+ virtual content::DevToolsExternalAgentProxyDelegate*
+ HandleWebSocketConnection(const std::string& path) = 0;
};
} // namespace devtools_http_handler
diff --git a/chromium/components/devtools_http_handler/devtools_http_handler_unittest.cc b/chromium/components/devtools_http_handler/devtools_http_handler_unittest.cc
index f2ce13d1da8..bc7f0bcc5d6 100644
--- a/chromium/components/devtools_http_handler/devtools_http_handler_unittest.cc
+++ b/chromium/components/devtools_http_handler/devtools_http_handler_unittest.cc
@@ -104,6 +104,11 @@ class DummyDelegate : public DevToolsHttpHandlerDelegate {
std::string GetPageThumbnailData(const GURL& url) override {
return std::string();
}
+
+ content::DevToolsExternalAgentProxyDelegate*
+ HandleWebSocketConnection(const std::string& path) override {
+ return nullptr;
+ }
};
}
diff --git a/chromium/components/devtools_service/BUILD.gn b/chromium/components/devtools_service/BUILD.gn
index a08eadb0008..02c6a7a82ca 100644
--- a/chromium/components/devtools_service/BUILD.gn
+++ b/chromium/components/devtools_service/BUILD.gn
@@ -4,6 +4,10 @@
import("//mojo/public/mojo_application.gni")
+# We don't support building mojo apps in the component build.
+# Currently this app is used by Mandoline only.
+assert(!is_component_build)
+
source_set("lib") {
sources = [
"devtools_agent_host.cc",
diff --git a/chromium/components/devtools_service/devtools_agent_host.cc b/chromium/components/devtools_service/devtools_agent_host.cc
index d31811a57c6..30b2287216c 100644
--- a/chromium/components/devtools_service/devtools_agent_host.cc
+++ b/chromium/components/devtools_service/devtools_agent_host.cc
@@ -4,18 +4,11 @@
#include "components/devtools_service/devtools_agent_host.h"
-#include "base/guid.h"
-#include "base/logging.h"
-
namespace devtools_service {
-DevToolsAgentHost::DevToolsAgentHost(DevToolsAgentPtr agent)
- : id_(base::GenerateGUID()),
- agent_(agent.Pass()),
- binding_(this),
- delegate_(nullptr) {
- agent_.set_error_handler(this);
-}
+DevToolsAgentHost::DevToolsAgentHost(const std::string& id,
+ DevToolsAgentPtr agent)
+ : id_(id), agent_(agent.Pass()), binding_(this), delegate_(nullptr) {}
DevToolsAgentHost::~DevToolsAgentHost() {
if (delegate_)
@@ -30,7 +23,7 @@ void DevToolsAgentHost::SetDelegate(Delegate* delegate) {
DevToolsAgentClientPtr client;
binding_.Bind(&client);
- agent_->SetClient(client.Pass(), id_);
+ agent_->SetClient(client.Pass());
} else {
if (!binding_.is_bound())
return;
@@ -43,12 +36,10 @@ void DevToolsAgentHost::SendProtocolMessageToAgent(const std::string& message) {
agent_->DispatchProtocolMessage(message);
}
-void DevToolsAgentHost::DispatchProtocolMessage(const mojo::String& message) {
+void DevToolsAgentHost::DispatchProtocolMessage(int32_t call_id,
+ const mojo::String& message,
+ const mojo::String& state) {
delegate_->DispatchProtocolMessage(this, message);
}
-void DevToolsAgentHost::OnConnectionError() {
- agent_connection_error_handler_.Run();
-}
-
} // namespace devtools_service
diff --git a/chromium/components/devtools_service/devtools_agent_host.h b/chromium/components/devtools_service/devtools_agent_host.h
index 7b5e759fcdf..131307a9e7e 100644
--- a/chromium/components/devtools_service/devtools_agent_host.h
+++ b/chromium/components/devtools_service/devtools_agent_host.h
@@ -11,13 +11,11 @@
#include "components/devtools_service/public/interfaces/devtools_service.mojom.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/callback.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
namespace devtools_service {
// DevToolsAgentHost represents a DevTools agent at the service side.
-class DevToolsAgentHost : public DevToolsAgentClient,
- public mojo::ErrorHandler {
+class DevToolsAgentHost : public DevToolsAgentClient {
public:
class Delegate {
public:
@@ -30,12 +28,12 @@ class DevToolsAgentHost : public DevToolsAgentClient,
virtual void OnAgentHostClosed(DevToolsAgentHost* agent_host) = 0;
};
- explicit DevToolsAgentHost(DevToolsAgentPtr agent);
+ DevToolsAgentHost(const std::string& id, DevToolsAgentPtr agent);
~DevToolsAgentHost() override;
void set_agent_connection_error_handler(const mojo::Closure& handler) {
- agent_connection_error_handler_ = handler;
+ agent_.set_connection_error_handler(handler);
}
std::string id() const { return id_; }
@@ -51,15 +49,13 @@ class DevToolsAgentHost : public DevToolsAgentClient,
private:
// DevToolsAgentClient implementation.
- void DispatchProtocolMessage(const mojo::String& message) override;
-
- // mojo::ErrorHandler implementation.
- void OnConnectionError() override;
+ void DispatchProtocolMessage(int32_t call_id,
+ const mojo::String& message,
+ const mojo::String& state) override;
const std::string id_;
DevToolsAgentPtr agent_;
- mojo::Closure agent_connection_error_handler_;
mojo::Binding<DevToolsAgentClient> binding_;
diff --git a/chromium/components/devtools_service/devtools_http_server.cc b/chromium/components/devtools_service/devtools_http_server.cc
index 372cd37d76c..0c7dcbbc075 100644
--- a/chromium/components/devtools_service/devtools_http_server.cc
+++ b/chromium/components/devtools_service/devtools_http_server.cc
@@ -47,6 +47,16 @@ const char kTargetUrlField[] = "url";
const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl";
const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl";
+std::string GetHeaderValue(const mojo::HttpRequest& request,
+ const std::string& name) {
+ for (size_t i = 0; i < request.headers.size(); ++i) {
+ if (name == request.headers[i]->name)
+ return request.headers[i]->value;
+ }
+
+ return std::string();
+}
+
bool ParseJsonPath(const std::string& path,
std::string* command,
std::string* target_id) {
@@ -115,8 +125,7 @@ mojo::HttpResponsePtr MakeJsonResponse(uint32_t status_code,
}
class WebSocketRelayer : public DevToolsAgentHost::Delegate,
- public mojo::WebSocketClient,
- public mojo::ErrorHandler {
+ public mojo::WebSocketClient {
public:
// Creates a WebSocketRelayer instance and sets it as the delegate of
// |agent_host|.
@@ -152,7 +161,7 @@ class WebSocketRelayer : public DevToolsAgentHost::Delegate,
write_send_stream_(new mojo::WebSocketWriteQueue(send_stream_.get())),
pending_send_count_(0),
pending_receive_count_(0) {
- web_socket_.set_error_handler(this);
+ web_socket_.set_connection_error_handler([this]() { OnConnectionError(); });
agent_host->SetDelegate(this);
}
@@ -227,8 +236,7 @@ class WebSocketRelayer : public DevToolsAgentHost::Delegate,
uint16_t code,
const mojo::String& reason) override {}
- // mojo::ErrorHandler implementation.
- void OnConnectionError() override {
+ void OnConnectionError() {
web_socket_ = nullptr;
binding_.Close();
@@ -281,8 +289,7 @@ class WebSocketRelayer : public DevToolsAgentHost::Delegate,
} // namespace
class DevToolsHttpServer::HttpConnectionDelegateImpl
- : public mojo::HttpConnectionDelegate,
- public mojo::ErrorHandler {
+ : public mojo::HttpConnectionDelegate {
public:
HttpConnectionDelegateImpl(
DevToolsHttpServer* owner,
@@ -295,8 +302,9 @@ class DevToolsHttpServer::HttpConnectionDelegateImpl
DCHECK(connection_);
DCHECK(binding_.is_bound());
- connection_.set_error_handler(this);
- binding_.set_error_handler(this);
+ auto error_handler = [this]() { owner_->OnConnectionClosed(this); };
+ connection_.set_connection_error_handler(error_handler);
+ binding_.set_connection_error_handler(error_handler);
}
mojo::HttpConnection* connection() { return connection_.get(); }
@@ -314,9 +322,6 @@ class DevToolsHttpServer::HttpConnectionDelegateImpl
owner_->OnReceivedWebSocketRequest(this, request.Pass(), callback);
}
- // mojo::ErrorHandler implementation.
- void OnConnectionError() override { owner_->OnConnectionClosed(this); }
-
DevToolsHttpServer* const owner_;
mojo::HttpConnectionPtr connection_;
mojo::Binding<HttpConnectionDelegate> binding_;
@@ -464,6 +469,12 @@ mojo::HttpResponsePtr DevToolsHttpServer::ProcessJsonRequest(
return nullptr;
}
+ std::string host = GetHeaderValue(*request, "host");
+ if (host.empty()) {
+ host = base::StringPrintf("127.0.0.1:%u",
+ static_cast<unsigned>(remote_debugging_port_));
+ }
+
base::ListValue list_value;
for (; !iter.IsAtEnd(); iter.Advance()) {
scoped_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue());
@@ -477,9 +488,8 @@ mojo::HttpResponsePtr DevToolsHttpServer::ProcessJsonRequest(
dict_value->SetString(kTargetUrlField, std::string());
dict_value->SetString(
kTargetWebSocketDebuggerUrlField,
- base::StringPrintf("ws://127.0.0.1:%u%s%s",
- static_cast<unsigned>(remote_debugging_port_),
- kPageUrlPrefix, iter.value()->id().c_str()));
+ base::StringPrintf("ws://%s%s%s", host.c_str(), kPageUrlPrefix,
+ iter.value()->id().c_str()));
list_value.Append(dict_value.Pass());
}
return MakeJsonResponse(200, &list_value, std::string());
diff --git a/chromium/components/devtools_service/devtools_http_server.h b/chromium/components/devtools_service/devtools_http_server.h
index a4f4eed1ff6..6906db689ff 100644
--- a/chromium/components/devtools_service/devtools_http_server.h
+++ b/chromium/components/devtools_service/devtools_http_server.h
@@ -12,6 +12,7 @@
#include "mojo/services/network/public/interfaces/http_connection.mojom.h"
#include "mojo/services/network/public/interfaces/http_message.mojom.h"
#include "mojo/services/network/public/interfaces/http_server.mojom.h"
+#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
namespace devtools_service {
diff --git a/chromium/components/devtools_service/devtools_registry_impl.cc b/chromium/components/devtools_service/devtools_registry_impl.cc
index 3fc7e0d3a6d..5e402e890ae 100644
--- a/chromium/components/devtools_service/devtools_registry_impl.cc
+++ b/chromium/components/devtools_service/devtools_registry_impl.cc
@@ -36,13 +36,14 @@ DevToolsAgentHost* DevToolsRegistryImpl::GetAgentById(const std::string& id) {
return iter->second.get();
}
-void DevToolsRegistryImpl::RegisterAgent(DevToolsAgentPtr agent) {
- linked_ptr<DevToolsAgentHost> agent_host(new DevToolsAgentHost(agent.Pass()));
- std::string id = agent_host->id();
+void DevToolsRegistryImpl::RegisterAgent(const mojo::String& id,
+ DevToolsAgentPtr agent) {
+ linked_ptr<DevToolsAgentHost> agent_host(
+ new DevToolsAgentHost(id, agent.Pass()));
agent_host->set_agent_connection_error_handler(
[this, id]() { OnAgentConnectionError(id); });
- agents_[agent_host->id()] = agent_host;
+ agents_[id] = agent_host;
}
void DevToolsRegistryImpl::OnAgentConnectionError(const std::string& id) {
diff --git a/chromium/components/devtools_service/devtools_registry_impl.h b/chromium/components/devtools_service/devtools_registry_impl.h
index 431f39a601c..64974f54318 100644
--- a/chromium/components/devtools_service/devtools_registry_impl.h
+++ b/chromium/components/devtools_service/devtools_registry_impl.h
@@ -46,7 +46,7 @@ class DevToolsRegistryImpl : public DevToolsRegistry {
private:
// DevToolsRegistry implementation.
- void RegisterAgent(DevToolsAgentPtr agent) override;
+ void RegisterAgent(const mojo::String& id, DevToolsAgentPtr agent) override;
void OnAgentConnectionError(const std::string& id);
diff --git a/chromium/components/devtools_service/devtools_service.cc b/chromium/components/devtools_service/devtools_service.cc
index 6cc0ede5ec0..36a8309465c 100644
--- a/chromium/components/devtools_service/devtools_service.cc
+++ b/chromium/components/devtools_service/devtools_service.cc
@@ -6,13 +6,12 @@
#include "base/logging.h"
#include "components/devtools_service/devtools_http_server.h"
-#include "components/devtools_service/devtools_registry_impl.h"
#include "mojo/application/public/cpp/application_impl.h"
namespace devtools_service {
DevToolsService::DevToolsService(mojo::ApplicationImpl* application)
- : application_(application) {
+ : application_(application), registry_(this) {
DCHECK(application_);
}
@@ -25,7 +24,7 @@ void DevToolsService::BindToCoordinatorRequest(
}
void DevToolsService::Initialize(uint16_t remote_debugging_port) {
- if (IsInitialized()) {
+ if (http_server_) {
LOG(WARNING) << "DevTools service receives a "
<< "DevToolsCoordinator.Initialize() call while it has "
<< "already been initialized.";
@@ -33,7 +32,6 @@ void DevToolsService::Initialize(uint16_t remote_debugging_port) {
}
http_server_.reset(new DevToolsHttpServer(this, remote_debugging_port));
- registry_.reset(new DevToolsRegistryImpl(this));
}
} // namespace devtools_service
diff --git a/chromium/components/devtools_service/devtools_service.h b/chromium/components/devtools_service/devtools_service.h
index a1385a6f081..d6c00847aa2 100644
--- a/chromium/components/devtools_service/devtools_service.h
+++ b/chromium/components/devtools_service/devtools_service.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "components/devtools_service/devtools_registry_impl.h"
#include "components/devtools_service/public/interfaces/devtools_service.mojom.h"
#include "mojo/common/weak_binding_set.h"
@@ -17,7 +18,6 @@ class ApplicationImpl;
namespace devtools_service {
class DevToolsHttpServer;
-class DevToolsRegistryImpl;
// DevToolsService is the central control. It manages the communication with
// DevTools agents (e.g., Web page renderers). It also starts an HTTP server to
@@ -33,10 +33,7 @@ class DevToolsService : public DevToolsCoordinator {
mojo::ApplicationImpl* application() { return application_; }
- bool IsInitialized() const { return !!http_server_; }
-
- // Non-null if initialized.
- DevToolsRegistryImpl* registry() { return registry_.get(); }
+ DevToolsRegistryImpl* registry() { return &registry_; }
private:
// DevToolsCoordinator implementation.
@@ -48,7 +45,7 @@ class DevToolsService : public DevToolsCoordinator {
mojo::WeakBindingSet<DevToolsCoordinator> coordinator_bindings_;
scoped_ptr<DevToolsHttpServer> http_server_;
- scoped_ptr<DevToolsRegistryImpl> registry_;
+ DevToolsRegistryImpl registry_;
DISALLOW_COPY_AND_ASSIGN(DevToolsService);
};
diff --git a/chromium/components/devtools_service/devtools_service_delegate.cc b/chromium/components/devtools_service/devtools_service_delegate.cc
index 137d06d2443..ae96d2c72fa 100644
--- a/chromium/components/devtools_service/devtools_service_delegate.cc
+++ b/chromium/components/devtools_service/devtools_service_delegate.cc
@@ -52,8 +52,7 @@ void DevToolsServiceDelegate::Quit() {
void DevToolsServiceDelegate::Create(
mojo::ApplicationConnection* connection,
mojo::InterfaceRequest<DevToolsRegistry> request) {
- if (service_->IsInitialized())
- service_->registry()->BindToRegistryRequest(request.Pass());
+ service_->registry()->BindToRegistryRequest(request.Pass());
}
void DevToolsServiceDelegate::Create(
diff --git a/chromium/components/devtools_service/public/interfaces/devtools_service.mojom b/chromium/components/devtools_service/public/interfaces/devtools_service.mojom
index 80a2ad880dc..83d4750ebc0 100644
--- a/chromium/components/devtools_service/public/interfaces/devtools_service.mojom
+++ b/chromium/components/devtools_service/public/interfaces/devtools_service.mojom
@@ -21,8 +21,10 @@ interface DevToolsCoordinator {
};
interface DevToolsRegistry {
- // Registers a DevTools agent.
- RegisterAgent(DevToolsAgent agent);
+ // Registers a DevTools agent. |id| is the agent ID, which is used to identify
+ // the agent when the service and its clients communicate using the Chrome
+ // remote debugging protocol.
+ RegisterAgent(string id, DevToolsAgent agent);
};
interface DevToolsAgent {
@@ -30,14 +32,17 @@ interface DevToolsAgent {
// DispatchProtocolMessage() calls. If a client doesn't want to receive
// messages anymore, it could simply close the underlying message pipe of
// |client|.
- SetClient(DevToolsAgentClient client, string client_id);
+ SetClient(DevToolsAgentClient client);
// Sends a command (in remote debugging protocol JSON format) to the agent.
DispatchProtocolMessage(string message);
};
interface DevToolsAgentClient {
- // Sends a notification or response message (in remote debugging protocol JSON
- // format) to the client.
- DispatchProtocolMessage(string message);
+ // Sends a notification or response message to the client. |message| is in
+ // remote debugging protocol JSON format. |call_id| is the "id" field of the
+ // message or 0 if such a field doesn't exist. If not empty or null, |state|
+ // is the state of the DevTools agent at the point when generating this
+ // message.
+ DispatchProtocolMessage(int32 call_id, string message, string? state);
};
diff --git a/chromium/components/dom_distiller.gypi b/chromium/components/dom_distiller.gypi
index 157e6be58bf..8d3165596f1 100644
--- a/chromium/components/dom_distiller.gypi
+++ b/chromium/components/dom_distiller.gypi
@@ -39,13 +39,14 @@
'../base/base.gyp:base_prefs',
'../skia/skia.gyp:skia',
'../sync/sync.gyp:sync',
- '../third_party/re2/re2.gyp:re2',
'../third_party/dom_distiller_js/dom_distiller_js.gyp:dom_distiller_js_proto',
+ '../third_party/re2/re2.gyp:re2',
'components.gyp:leveldb_proto',
'components_resources.gyp:components_resources',
'components_strings.gyp:components_strings',
'dom_distiller_protos',
'pref_registry',
+ 'variations',
],
'include_dirs': [
'..',
@@ -79,6 +80,8 @@
'dom_distiller/core/distiller_url_fetcher.h',
'dom_distiller/core/dom_distiller_constants.cc',
'dom_distiller/core/dom_distiller_constants.h',
+ 'dom_distiller/core/dom_distiller_features.cc',
+ 'dom_distiller/core/dom_distiller_features.h',
'dom_distiller/core/dom_distiller_model.cc',
'dom_distiller/core/dom_distiller_model.h',
'dom_distiller/core/dom_distiller_observer.h',
@@ -94,7 +97,6 @@
'dom_distiller/core/dom_distiller_switches.h',
'dom_distiller/core/experiments.cc',
'dom_distiller/core/experiments.h',
- 'dom_distiller/core/external_feedback_reporter.h',
'dom_distiller/core/feedback_reporter.cc',
'dom_distiller/core/feedback_reporter.h',
'dom_distiller/core/font_family_list.h',
@@ -159,43 +161,61 @@
},
'includes': [ '../build/protoc.gypi' ]
},
+ {
+ # GN version: //components/dom_distiller/content:mojo_bindings
+ 'target_name': 'dom_distiller_mojo_bindings',
+ 'type': 'static_library',
+ 'sources': [
+ 'dom_distiller/content/common/distiller_javascript_service.mojom',
+ 'dom_distiller/content/common/distiller_page_notifier_service.mojom',
+ ],
+ 'includes': [
+ '../third_party/mojo/mojom_bindings_generator.gypi',
+ ],
+ },
],
'conditions': [
['OS != "ios"', {
'targets': [
{
- # GN version: //components/dom_distiller/content
- 'target_name': 'dom_distiller_content',
+ # GN version: //components/dom_distiller/content:content_browser
+ 'target_name': 'dom_distiller_content_browser',
'type': 'static_library',
'dependencies': [
+ 'dom_distiller_core',
+ 'dom_distiller_mojo_bindings',
+ 'dom_distiller_protos',
'../base/base.gyp:base',
'../content/content.gyp:content_browser',
+ '../mojo/mojo_base.gyp:mojo_environment_chromium',
'../net/net.gyp:net',
'../skia/skia.gyp:skia',
'../sync/sync.gyp:sync',
+ '../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings',
'../ui/gfx/gfx.gyp:gfx',
'../url/url.gyp:url_lib',
'components_resources.gyp:components_resources',
'components_strings.gyp:components_strings',
- 'dom_distiller_core',
- 'dom_distiller_protos',
],
'include_dirs': [
'..',
],
'sources': [
- 'dom_distiller/content/distillable_page_utils.cc',
- 'dom_distiller/content/distillable_page_utils.h',
- 'dom_distiller/content/distillable_page_utils_android.cc',
- 'dom_distiller/content/distillable_page_utils_android.h',
- 'dom_distiller/content/distiller_javascript_utils.cc',
- 'dom_distiller/content/distiller_javascript_utils.h',
- 'dom_distiller/content/distiller_page_web_contents.cc',
- 'dom_distiller/content/distiller_page_web_contents.h',
- 'dom_distiller/content/dom_distiller_viewer_source.cc',
- 'dom_distiller/content/dom_distiller_viewer_source.h',
- 'dom_distiller/content/web_contents_main_frame_observer.cc',
- 'dom_distiller/content/web_contents_main_frame_observer.h',
+ 'dom_distiller/content/browser/distillable_page_utils.cc',
+ 'dom_distiller/content/browser/distillable_page_utils.h',
+ 'dom_distiller/content/browser/distillable_page_utils_android.cc',
+ 'dom_distiller/content/browser/distillable_page_utils_android.h',
+ 'dom_distiller/content/browser/distiller_javascript_service_impl.cc',
+ 'dom_distiller/content/browser/distiller_javascript_service_impl.h',
+ 'dom_distiller/content/browser/distiller_javascript_utils.cc',
+ 'dom_distiller/content/browser/distiller_javascript_utils.h',
+ 'dom_distiller/content/browser/distiller_page_web_contents.cc',
+ 'dom_distiller/content/browser/distiller_page_web_contents.h',
+ 'dom_distiller/content/browser/dom_distiller_viewer_source.cc',
+ 'dom_distiller/content/browser/dom_distiller_viewer_source.h',
+ 'dom_distiller/content/browser/external_feedback_reporter.h',
+ 'dom_distiller/content/browser/web_contents_main_frame_observer.cc',
+ 'dom_distiller/content/browser/web_contents_main_frame_observer.h',
],
'conditions': [
['OS == "android"', {
@@ -206,6 +226,31 @@
}],
],
},
+ {
+ # GN version: //components/dom_distiller/content:content_renderer
+ 'target_name': 'dom_distiller_content_renderer',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'dom_distiller_mojo_bindings',
+ '../base/base.gyp:base',
+ '../content/content.gyp:content_browser',
+ '../gin/gin.gyp:gin',
+ '../mojo/mojo_base.gyp:mojo_environment_chromium',
+ '../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'dom_distiller/content/renderer/distiller_js_render_frame_observer.cc',
+ 'dom_distiller/content/renderer/distiller_js_render_frame_observer.h',
+ 'dom_distiller/content/renderer/distiller_native_javascript.cc',
+ 'dom_distiller/content/renderer/distiller_native_javascript.h',
+ 'dom_distiller/content/renderer/distiller_page_notifier_service_impl.cc',
+ 'dom_distiller/content/renderer/distiller_page_notifier_service_impl.h',
+ ],
+ },
+
],
}],
['OS=="ios"', {
diff --git a/chromium/components/dom_distiller_strings.grdp b/chromium/components/dom_distiller_strings.grdp
index 5a8cfad381b..fc9f1a9e374 100644
--- a/chromium/components/dom_distiller_strings.grdp
+++ b/chromium/components/dom_distiller_strings.grdp
@@ -26,10 +26,10 @@
Fetching entries...
</message>
<message name="IDS_DOM_DISTILLER_VIEWER_CLOSE_READER_VIEW" desc="The text to show on a button at the bottom of the page to close reader view.">
- Close mobile-friendly view
+ Close
</message>
<message name="IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_TITLE" desc="The text to show in place of a reading list article title if the article is not found.">
- Failed to find article.
+ Failed to find article
</message>
<message name="IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_CONTENT" desc="The text to show in place of reading list article content if the article is not found.">
Could not find the requested article.
@@ -37,9 +37,6 @@
<message name="IDS_DOM_DISTILLER_VIEWER_LOADING_TITLE" desc="The text to show in place of a reading list article title while the article is loading.">
Reader Mode
</message>
- <message name="IDS_DOM_DISTILLER_VIEWER_NO_DATA_TITLE" desc="The text to show in place of a reading list article title if there is no data found.">
- Failed to display article.
- </message>
<message name="IDS_DOM_DISTILLER_VIEWER_NO_DATA_CONTENT" desc="The text to show in place of reading list article content if there is no data found.">
No data found.
</message>
diff --git a/chromium/components/domain_reliability.gypi b/chromium/components/domain_reliability.gypi
index 9b1d7d5820e..4412b612aeb 100644
--- a/chromium/components/domain_reliability.gypi
+++ b/chromium/components/domain_reliability.gypi
@@ -14,6 +14,7 @@
'dependencies': [
'../base/base.gyp:base',
'../base/base.gyp:base_prefs',
+ '../components/components.gyp:data_use_measurement_core',
'../components/components.gyp:keyed_service_core',
'../content/content.gyp:content_browser',
'../net/net.gyp:net',
diff --git a/chromium/components/drive.gypi b/chromium/components/drive.gypi
new file mode 100644
index 00000000000..781f54617a0
--- /dev/null
+++ b/chromium/components/drive.gypi
@@ -0,0 +1,176 @@
+# 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.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/drive:drive
+ 'target_name': 'drive',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ 'drive_proto',
+ '../base/base.gyp:base',
+ '../components/components.gyp:invalidation_public',
+
+ # TODO(lukasza): Remove this dependency (see DEPS file for more info).
+ '../content/content.gyp:content_browser',
+
+ '../google_apis/google_apis.gyp:google_apis',
+ '../net/net.gyp:net',
+ '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation',
+ '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_proto_cpp',
+ '../third_party/leveldatabase/leveldatabase.gyp:leveldatabase',
+ '../third_party/re2/re2.gyp:re2',
+ ],
+ 'sources': [
+ 'drive/change_list_loader.cc',
+ 'drive/change_list_loader.h',
+ 'drive/change_list_loader_observer.h',
+ 'drive/change_list_processor.cc',
+ 'drive/change_list_processor.h',
+ 'drive/directory_loader.cc',
+ 'drive/directory_loader.h',
+ 'drive/drive_api_util.cc',
+ 'drive/drive_api_util.h',
+ 'drive/drive_app_registry.cc',
+ 'drive/drive_app_registry.h',
+ 'drive/drive_app_registry_observer.h',
+ 'drive/drive_notification_manager.cc',
+ 'drive/drive_notification_manager.h',
+ 'drive/drive_notification_observer.h',
+ 'drive/drive_pref_names.cc',
+ 'drive/drive_pref_names.h',
+ 'drive/drive_uploader.cc',
+ 'drive/drive_uploader.h',
+ 'drive/event_logger.cc',
+ 'drive/event_logger.h',
+ 'drive/file_cache.cc',
+ 'drive/file_cache.h',
+ 'drive/file_change.cc',
+ 'drive/file_change.h',
+ 'drive/file_errors.cc',
+ 'drive/file_errors.h',
+ 'drive/file_system.cc',
+ 'drive/file_system.h',
+ 'drive/file_system/copy_operation.cc',
+ 'drive/file_system/copy_operation.h',
+ 'drive/file_system/create_directory_operation.cc',
+ 'drive/file_system/create_directory_operation.h',
+ 'drive/file_system/create_file_operation.cc',
+ 'drive/file_system/create_file_operation.h',
+ 'drive/file_system/download_operation.cc',
+ 'drive/file_system/download_operation.h',
+ 'drive/file_system/get_file_for_saving_operation.cc',
+ 'drive/file_system/get_file_for_saving_operation.h',
+ 'drive/file_system/move_operation.cc',
+ 'drive/file_system/move_operation.h',
+ 'drive/file_system/open_file_operation.cc',
+ 'drive/file_system/open_file_operation.h',
+ 'drive/file_system/operation_delegate.cc',
+ 'drive/file_system/operation_delegate.h',
+ 'drive/file_system/remove_operation.cc',
+ 'drive/file_system/remove_operation.h',
+ 'drive/file_system/search_operation.cc',
+ 'drive/file_system/search_operation.h',
+ 'drive/file_system/set_property_operation.cc',
+ 'drive/file_system/set_property_operation.h',
+ 'drive/file_system/touch_operation.cc',
+ 'drive/file_system/touch_operation.h',
+ 'drive/file_system/truncate_operation.cc',
+ 'drive/file_system/truncate_operation.h',
+ 'drive/file_system_core_util.cc',
+ 'drive/file_system_core_util.h',
+ 'drive/file_system_interface.cc',
+ 'drive/file_system_interface.h',
+ 'drive/file_system_metadata.cc',
+ 'drive/file_system_metadata.h',
+ 'drive/file_system_observer.h',
+ 'drive/file_write_watcher.cc',
+ 'drive/file_write_watcher.h',
+ 'drive/job_list.cc',
+ 'drive/job_list.h',
+ 'drive/job_queue.cc',
+ 'drive/job_queue.h',
+ 'drive/job_scheduler.cc',
+ 'drive/job_scheduler.h',
+ 'drive/local_file_reader.cc',
+ 'drive/local_file_reader.h',
+ 'drive/remove_stale_cache_files.cc',
+ 'drive/remove_stale_cache_files.h',
+ 'drive/resource_entry_conversion.cc',
+ 'drive/resource_entry_conversion.h',
+ 'drive/resource_metadata.cc',
+ 'drive/resource_metadata.h',
+ 'drive/resource_metadata_storage.cc',
+ 'drive/resource_metadata_storage.h',
+ 'drive/search_metadata.cc',
+ 'drive/search_metadata.h',
+ 'drive/service/drive_api_service.cc',
+ 'drive/service/drive_api_service.h',
+ 'drive/service/drive_service_interface.cc',
+ 'drive/service/drive_service_interface.h',
+ 'drive/sync/entry_revert_performer.cc',
+ 'drive/sync/entry_revert_performer.h',
+ 'drive/sync/entry_update_performer.cc',
+ 'drive/sync/entry_update_performer.h',
+ 'drive/sync/remove_performer.cc',
+ 'drive/sync/remove_performer.h',
+ 'drive/sync_client.cc',
+ 'drive/sync_client.h',
+ ],
+ },
+
+ {
+ # GN version: //components/drive:proto
+ # Protobuf compiler / generator for the Drive protocol buffer.
+ 'target_name': 'drive_proto',
+ 'type': 'static_library',
+ 'sources': [ 'drive/drive.proto' ],
+ 'variables': {
+ 'proto_in_dir': 'drive',
+ 'proto_out_dir': 'components/drive',
+ },
+ 'includes': [ '../build/protoc.gypi' ]
+ },
+
+ {
+ # GN version: //components/drive:test_support
+ 'target_name': 'drive_test_support',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ 'drive',
+ 'drive_proto',
+ '../base/base.gyp:base',
+ '../content/content_shell_and_tests.gyp:test_support_content',
+ '../google_apis/google_apis.gyp:google_apis',
+ '../net/net.gyp:net',
+ ],
+ 'sources': [
+ "drive/drive_test_util.cc",
+ "drive/drive_test_util.h",
+ "drive/dummy_file_system.cc",
+ "drive/dummy_file_system.h",
+ "drive/fake_file_system.cc",
+ "drive/fake_file_system.h",
+ "drive/fake_free_disk_space_getter.cc",
+ "drive/fake_free_disk_space_getter.h",
+ "drive/service/dummy_drive_service.cc",
+ "drive/service/dummy_drive_service.h",
+ "drive/service/fake_drive_service.cc",
+ "drive/service/fake_drive_service.h",
+ "drive/service/test_util.cc",
+ "drive/service/test_util.h",
+ ],
+ },
+
+ # TODO(lukasza): drive_unittests target.
+ # Currently tests are built as part of chrome/chrome_tests_unit.gypi.
+ ],
+}
diff --git a/chromium/components/enhanced_bookmarks.gypi b/chromium/components/enhanced_bookmarks.gypi
index be15b26bc41..d9d895303d8 100644
--- a/chromium/components/enhanced_bookmarks.gypi
+++ b/chromium/components/enhanced_bookmarks.gypi
@@ -24,17 +24,20 @@
'keyed_service_core',
'signin_core_browser',
'sync_driver',
+ 'variations',
],
'sources': [
- 'enhanced_bookmarks/bookmark_image_service.cc',
- 'enhanced_bookmarks/bookmark_image_service.h',
'enhanced_bookmarks/bookmark_server_cluster_service.cc',
'enhanced_bookmarks/bookmark_server_cluster_service.h',
'enhanced_bookmarks/bookmark_server_service.cc',
'enhanced_bookmarks/bookmark_server_service.h',
+ 'enhanced_bookmarks/enhanced_bookmark_features.cc',
+ 'enhanced_bookmarks/enhanced_bookmark_features.h',
'enhanced_bookmarks/enhanced_bookmark_model.cc',
'enhanced_bookmarks/enhanced_bookmark_model.h',
'enhanced_bookmarks/enhanced_bookmark_model_observer.h',
+ 'enhanced_bookmarks/enhanced_bookmark_switches.cc',
+ 'enhanced_bookmarks/enhanced_bookmark_switches.h',
'enhanced_bookmarks/enhanced_bookmark_utils.cc',
'enhanced_bookmarks/enhanced_bookmark_utils.h',
'enhanced_bookmarks/image_record.cc',
@@ -69,6 +72,7 @@
'..',
],
'dependencies': [
+ '../skia/skia.gyp:skia',
'../testing/gtest.gyp:gtest',
'enhanced_bookmarks',
],
diff --git a/chromium/components/error_page.gypi b/chromium/components/error_page.gypi
index a281610a140..bc465cc38a3 100644
--- a/chromium/components/error_page.gypi
+++ b/chromium/components/error_page.gypi
@@ -11,6 +11,7 @@
'dependencies': [
'../base/base.gyp:base',
'../url/url.gyp:url_lib',
+ 'url_formatter/url_formatter.gyp:url_formatter',
],
'include_dirs': [
'..',
diff --git a/chromium/components/error_page/common/net_error_info.cc b/chromium/components/error_page/common/net_error_info.cc
index 7483e737983..1ac72644b31 100644
--- a/chromium/components/error_page/common/net_error_info.cc
+++ b/chromium/components/error_page/common/net_error_info.cc
@@ -7,35 +7,34 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
-namespace chrome_common_net {
+namespace error_page {
const char kDnsProbeErrorDomain[] = "dnsprobe";
const char* DnsProbeStatusToString(int status) {
switch (status) {
- case DNS_PROBE_POSSIBLE:
- return "DNS_PROBE_POSSIBLE";
- case DNS_PROBE_NOT_RUN:
- return "DNS_PROBE_NOT_RUN";
- case DNS_PROBE_STARTED:
- return "DNS_PROBE_STARTED";
- case DNS_PROBE_FINISHED_INCONCLUSIVE:
- return "DNS_PROBE_FINISHED_INCONCLUSIVE";
- case DNS_PROBE_FINISHED_NO_INTERNET:
- return "DNS_PROBE_FINISHED_NO_INTERNET";
- case DNS_PROBE_FINISHED_BAD_CONFIG:
- return "DNS_PROBE_FINISHED_BAD_CONFIG";
- case DNS_PROBE_FINISHED_NXDOMAIN:
- return "DNS_PROBE_FINISHED_NXDOMAIN";
- default:
- NOTREACHED();
- return "";
+ case DNS_PROBE_POSSIBLE:
+ return "DNS_PROBE_POSSIBLE";
+ case DNS_PROBE_NOT_RUN:
+ return "DNS_PROBE_NOT_RUN";
+ case DNS_PROBE_STARTED:
+ return "DNS_PROBE_STARTED";
+ case DNS_PROBE_FINISHED_INCONCLUSIVE:
+ return "DNS_PROBE_FINISHED_INCONCLUSIVE";
+ case DNS_PROBE_FINISHED_NO_INTERNET:
+ return "DNS_PROBE_FINISHED_NO_INTERNET";
+ case DNS_PROBE_FINISHED_BAD_CONFIG:
+ return "DNS_PROBE_FINISHED_BAD_CONFIG";
+ case DNS_PROBE_FINISHED_NXDOMAIN:
+ return "DNS_PROBE_FINISHED_NXDOMAIN";
+ default:
+ NOTREACHED();
+ return "";
}
}
bool DnsProbeStatusIsFinished(DnsProbeStatus status) {
- return status >= DNS_PROBE_FINISHED_INCONCLUSIVE &&
- status < DNS_PROBE_MAX;
+ return status >= DNS_PROBE_FINISHED_INCONCLUSIVE && status < DNS_PROBE_MAX;
}
void RecordEvent(NetworkErrorPageEvent event) {
@@ -43,4 +42,4 @@ void RecordEvent(NetworkErrorPageEvent event) {
NETWORK_ERROR_PAGE_EVENT_MAX);
}
-} // namespace chrome_common_net
+} // namespace error_page
diff --git a/chromium/components/error_page/common/net_error_info.h b/chromium/components/error_page/common/net_error_info.h
index 39b6aaedd32..77d6a283b2a 100644
--- a/chromium/components/error_page/common/net_error_info.h
+++ b/chromium/components/error_page/common/net_error_info.h
@@ -5,8 +5,7 @@
#ifndef COMPONENTS_ERROR_PAGE_COMMON_NET_ERROR_INFO_H_
#define COMPONENTS_ERROR_PAGE_COMMON_NET_ERROR_INFO_H_
-// TODO(hashimoto): Change this to namespace error_page.
-namespace chrome_common_net {
+namespace error_page {
// Network error page events. Used for UMA statistics.
enum NetworkErrorPageEvent {
@@ -33,13 +32,16 @@ enum NetworkErrorPageEvent {
NETWORK_ERROR_EASTER_EGG_ACTIVATED = 12, // Easter egg activated.
- // For "Google cached copy" label experiment button.
+ // For "Google cached copy" button experiment.
NETWORK_ERROR_PAGE_CACHED_COPY_BUTTON_SHOWN = 13,
NETWORK_ERROR_PAGE_CACHED_COPY_BUTTON_CLICKED = 14,
- NETWORK_ERROR_PAGE_CACHED_PAGE_BUTTON_SHOWN = 15,
- NETWORK_ERROR_PAGE_CACHED_PAGE_BUTTON_CLICKED = 16,
+ // Obsolete. No longer experimenting with the label.
+ // NETWORK_ERROR_PAGE_CACHED_PAGE_BUTTON_SHOWN = 15,
+ // NETWORK_ERROR_PAGE_CACHED_PAGE_BUTTON_CLICKED = 16,
- NETWORK_ERROR_PAGE_EVENT_MAX = 17,
+ NETWORK_ERROR_DIAGNOSE_BUTTON_CLICKED = 17, // Diagnose button clicked.
+
+ NETWORK_ERROR_PAGE_EVENT_MAX,
};
// The status of a DNS probe.
@@ -101,6 +103,6 @@ void RecordEvent(NetworkErrorPageEvent event);
// code.
extern const char kDnsProbeErrorDomain[];
-} // namespace chrome_common_net
+} // namespace error_page
#endif // COMPONENTS_ERROR_PAGE_COMMON_NET_ERROR_INFO_H_
diff --git a/chromium/components/error_page/renderer/BUILD.gn b/chromium/components/error_page/renderer/BUILD.gn
index e47fd699b3c..d564e4d5735 100644
--- a/chromium/components/error_page/renderer/BUILD.gn
+++ b/chromium/components/error_page/renderer/BUILD.gn
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-static_library("renderer") {
+source_set("renderer") {
sources = [
"net_error_helper_core.cc",
"net_error_helper_core.h",
@@ -12,6 +12,7 @@ static_library("renderer") {
"//base",
"//components/error_page/common",
"//components/strings",
+ "//components/url_formatter",
"//content/public/common",
"//net",
"//third_party/WebKit/public:blink",
@@ -19,3 +20,17 @@ static_library("renderer") {
"//url",
]
}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "net_error_helper_core_unittest.cc",
+ ]
+
+ configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+
+ deps = [
+ ":renderer",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/error_page/renderer/DEPS b/chromium/components/error_page/renderer/DEPS
index 5d271a948c1..3d7c4cefe96 100644
--- a/chromium/components/error_page/renderer/DEPS
+++ b/chromium/components/error_page/renderer/DEPS
@@ -1,4 +1,6 @@
include_rules = [
+ "+components/test_runner",
+ "+components/url_formatter",
"+content/public/common",
"+grit/components_strings.h",
"+net",
diff --git a/chromium/components/error_page/renderer/net_error_helper_core.cc b/chromium/components/error_page/renderer/net_error_helper_core.cc
index e7a3b85fdb2..60e2eeaf4e1 100644
--- a/chromium/components/error_page/renderer/net_error_helper_core.cc
+++ b/chromium/components/error_page/renderer/net_error_helper_core.cc
@@ -23,11 +23,11 @@
#include "base/strings/string_util.h"
#include "base/values.h"
#include "components/error_page/common/error_page_params.h"
+#include "components/url_formatter/url_formatter.h"
#include "content/public/common/url_constants.h"
#include "grit/components_strings.h"
#include "net/base/escape.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLError.h"
#include "ui/base/l10n/l10n_util.h"
@@ -38,21 +38,6 @@ namespace error_page {
namespace {
-// Recorded when a user interacts with an error page, part of investigation into
-// http://crbug.com/500556. Note that these are flags that can be or-ed
-// together.
-// TODO(mmenke): Remove when http://crbug.com/500556 is fixed.
-enum ErrorPageUnexpectedStateFlags {
- // According to blink, the page reporting a button press is not an error page.
- ERROR_PAGE_BUTTON_PRESS_FOR_NON_ERROR_PAGE_URL = 0x1,
- // NetErrorHelperCore's state machine things the current page is not an error
- // page.
- ERROR_PAGE_BUTTON_PRESS_WITH_NO_ERROR_INFO = 0x2,
-
- // Must be strictly greater than a value with all flags set.
- ERROR_PAGE_BUTTON_PRESS_MAX = 0x4,
-};
-
struct CorrectionTypeToResourceTable {
int resource_id;
const char* correction_type;
@@ -146,7 +131,7 @@ GURL SanitizeURL(const GURL& url) {
// Sanitizes and formats a URL for upload to the error correction service.
std::string PrepareUrlForUpload(const GURL& url) {
- // TODO(yuusuke): Change to net::FormatUrl when Link Doctor becomes
+ // TODO(yuusuke): Change to url_formatter::FormatUrl when Link Doctor becomes
// unicode-capable.
std::string spec_to_send = SanitizeURL(url).spec();
@@ -265,9 +250,9 @@ std::string CreateClickTrackingUrlRequestBody(
base::string16 FormatURLForDisplay(const GURL& url, bool is_rtl,
const std::string accept_languages) {
// Translate punycode into UTF8, unescape UTF8 URLs.
- base::string16 url_for_display(net::FormatUrl(
- url, accept_languages, net::kFormatUrlOmitNothing,
- net::UnescapeRule::NORMAL, NULL, NULL, NULL));
+ base::string16 url_for_display(url_formatter::FormatUrl(
+ url, accept_languages, url_formatter::kFormatUrlOmitNothing,
+ net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr));
// URLs are always LTR.
if (is_rtl)
base::i18n::WrapStringWithLTRFormatting(&url_for_display);
@@ -391,7 +376,6 @@ struct NetErrorHelperCore::ErrorPageInfo {
needs_load_navigation_corrections(false),
reload_button_in_page(false),
show_saved_copy_button_in_page(false),
- show_cached_page_button_in_page(false),
show_cached_copy_button_in_page(false),
is_finished_loading(false),
auto_reload_triggered(false) {
@@ -426,7 +410,6 @@ struct NetErrorHelperCore::ErrorPageInfo {
// Track if specific buttons are included in an error page, for statistics.
bool reload_button_in_page;
bool show_saved_copy_button_in_page;
- bool show_cached_page_button_in_page;
bool show_cached_copy_button_in_page;
// True if a page has completed loading, at which point it can receive
@@ -470,7 +453,8 @@ NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate,
bool auto_reload_visible_only,
bool is_visible)
: delegate_(delegate),
- last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE),
+ last_probe_status_(DNS_PROBE_POSSIBLE),
+ can_show_network_diagnostics_dialog_(false),
auto_reload_enabled_(auto_reload_enabled),
auto_reload_visible_only_(auto_reload_visible_only),
auto_reload_timer_(new base::Timer(false, false)),
@@ -569,10 +553,9 @@ void NetErrorHelperCore::OnCommitLoad(FrameType frame_type, const GURL& url) {
pending_error_page_info_->error.unreachableURL) {
DCHECK(navigation_from_button_ == RELOAD_BUTTON ||
navigation_from_button_ == SHOW_SAVED_COPY_BUTTON);
- chrome_common_net::RecordEvent(
- navigation_from_button_ == RELOAD_BUTTON ?
- chrome_common_net::NETWORK_ERROR_PAGE_RELOAD_BUTTON_ERROR :
- chrome_common_net::NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_ERROR);
+ RecordEvent(navigation_from_button_ == RELOAD_BUTTON ?
+ NETWORK_ERROR_PAGE_RELOAD_BUTTON_ERROR :
+ NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_ERROR);
}
navigation_from_button_ = NO_BUTTON;
@@ -600,26 +583,19 @@ void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) {
committed_error_page_info_->is_finished_loading = true;
- chrome_common_net::RecordEvent(chrome_common_net::NETWORK_ERROR_PAGE_SHOWN);
+ RecordEvent(NETWORK_ERROR_PAGE_SHOWN);
if (committed_error_page_info_->reload_button_in_page) {
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_RELOAD_BUTTON_SHOWN);
+ RecordEvent(NETWORK_ERROR_PAGE_RELOAD_BUTTON_SHOWN);
}
if (committed_error_page_info_->show_saved_copy_button_in_page) {
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_SHOWN);
+ RecordEvent(NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_SHOWN);
}
if (committed_error_page_info_->reload_button_in_page &&
committed_error_page_info_->show_saved_copy_button_in_page) {
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_BOTH_BUTTONS_SHOWN);
+ RecordEvent(NETWORK_ERROR_PAGE_BOTH_BUTTONS_SHOWN);
}
if (committed_error_page_info_->show_cached_copy_button_in_page) {
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_CACHED_COPY_BUTTON_SHOWN);
- } else if (committed_error_page_info_->show_cached_page_button_in_page) {
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_CACHED_PAGE_BUTTON_SHOWN);
+ RecordEvent(NETWORK_ERROR_PAGE_CACHED_COPY_BUTTON_SHOWN);
}
delegate_->EnablePageHelperFunctions();
@@ -640,7 +616,7 @@ void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) {
}
if (!committed_error_page_info_->needs_dns_updates ||
- last_probe_status_ == chrome_common_net::DNS_PROBE_POSSIBLE) {
+ last_probe_status_ == DNS_PROBE_POSSIBLE) {
return;
}
DVLOG(1) << "Error page finished loading; sending saved status.";
@@ -667,19 +643,18 @@ void NetErrorHelperCore::GetErrorHTML(
bool reload_button_in_page;
bool show_saved_copy_button_in_page;
bool show_cached_copy_button_in_page;
- bool show_cached_page_button_in_page;
delegate_->GenerateLocalizedErrorPage(
- error, is_failed_post, scoped_ptr<ErrorPageParams>(),
- &reload_button_in_page, &show_saved_copy_button_in_page,
- &show_cached_copy_button_in_page, &show_cached_page_button_in_page,
+ error, is_failed_post,
+ false /* No diagnostics dialogs allowed for subframes. */,
+ scoped_ptr<ErrorPageParams>(), &reload_button_in_page,
+ &show_saved_copy_button_in_page, &show_cached_copy_button_in_page,
error_html);
}
}
-void NetErrorHelperCore::OnNetErrorInfo(
- chrome_common_net::DnsProbeStatus status) {
- DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, status);
+void NetErrorHelperCore::OnNetErrorInfo(DnsProbeStatus status) {
+ DCHECK_NE(DNS_PROBE_POSSIBLE, status);
last_probe_status_ = status;
@@ -692,6 +667,11 @@ void NetErrorHelperCore::OnNetErrorInfo(
UpdateErrorPage();
}
+void NetErrorHelperCore::OnSetCanShowNetworkDiagnosticsDialog(
+ bool can_show_network_diagnostics_dialog) {
+ can_show_network_diagnostics_dialog_ = can_show_network_diagnostics_dialog;
+}
+
void NetErrorHelperCore::OnSetNavigationCorrectionInfo(
const GURL& navigation_correction_url,
const std::string& language,
@@ -724,33 +704,33 @@ void NetErrorHelperCore::GetErrorHtmlForMainFrame(
// loading, a DNS probe status scheduled to be sent to it may be thrown
// out, but since the new error page should trigger a new DNS probe, it
// will just get the results for the next page load.
- last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE;
+ last_probe_status_ = DNS_PROBE_POSSIBLE;
pending_error_page_info->needs_dns_updates = true;
error = GetUpdatedError(error);
}
delegate_->GenerateLocalizedErrorPage(
error, pending_error_page_info->was_failed_post,
+ can_show_network_diagnostics_dialog_,
scoped_ptr<ErrorPageParams>(),
&pending_error_page_info->reload_button_in_page,
&pending_error_page_info->show_saved_copy_button_in_page,
&pending_error_page_info->show_cached_copy_button_in_page,
- &pending_error_page_info->show_cached_page_button_in_page,
error_html);
}
void NetErrorHelperCore::UpdateErrorPage() {
DCHECK(committed_error_page_info_->needs_dns_updates);
DCHECK(committed_error_page_info_->is_finished_loading);
- DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, last_probe_status_);
+ DCHECK_NE(DNS_PROBE_POSSIBLE, last_probe_status_);
UMA_HISTOGRAM_ENUMERATION("DnsProbe.ErrorPageUpdateStatus",
last_probe_status_,
- chrome_common_net::DNS_PROBE_MAX);
+ DNS_PROBE_MAX);
// Every status other than DNS_PROBE_POSSIBLE and DNS_PROBE_STARTED is a
// final status code. Once one is reached, the page does not need further
// updates.
- if (last_probe_status_ != chrome_common_net::DNS_PROBE_STARTED)
+ if (last_probe_status_ != DNS_PROBE_STARTED)
committed_error_page_info_->needs_dns_updates = false;
// There is no need to worry about the button display statistics here because
@@ -758,7 +738,8 @@ void NetErrorHelperCore::UpdateErrorPage() {
// by a DNS error update.
delegate_->UpdateErrorPage(
GetUpdatedError(committed_error_page_info_->error),
- committed_error_page_info_->was_failed_post);
+ committed_error_page_info_->was_failed_post,
+ can_show_network_diagnostics_dialog_);
}
void NetErrorHelperCore::OnNavigationCorrectionsFetched(
@@ -794,11 +775,11 @@ void NetErrorHelperCore::OnNavigationCorrectionsFetched(
delegate_->GenerateLocalizedErrorPage(
pending_error_page_info_->error,
pending_error_page_info_->was_failed_post,
+ can_show_network_diagnostics_dialog_,
params.Pass(),
&pending_error_page_info_->reload_button_in_page,
&pending_error_page_info_->show_saved_copy_button_in_page,
&pending_error_page_info_->show_cached_copy_button_in_page,
- &pending_error_page_info_->show_cached_page_button_in_page,
&error_html);
} else {
// Since |navigation_correction_params| in |pending_error_page_info_| is
@@ -817,15 +798,13 @@ void NetErrorHelperCore::OnNavigationCorrectionsFetched(
blink::WebURLError NetErrorHelperCore::GetUpdatedError(
const blink::WebURLError& error) const {
// If a probe didn't run or wasn't conclusive, restore the original error.
- if (last_probe_status_ == chrome_common_net::DNS_PROBE_NOT_RUN ||
- last_probe_status_ ==
- chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE) {
+ if (last_probe_status_ == DNS_PROBE_NOT_RUN ||
+ last_probe_status_ == DNS_PROBE_FINISHED_INCONCLUSIVE) {
return error;
}
blink::WebURLError updated_error;
- updated_error.domain = blink::WebString::fromUTF8(
- chrome_common_net::kDnsProbeErrorDomain);
+ updated_error.domain = blink::WebString::fromUTF8(kDnsProbeErrorDomain);
updated_error.reason = last_probe_status_;
updated_error.unreachableURL = error.unreachableURL;
updated_error.staleCopyInCache = error.staleCopyInCache;
@@ -929,68 +908,43 @@ bool NetErrorHelperCore::ShouldSuppressErrorPage(FrameType frame_type,
return true;
}
-void NetErrorHelperCore::ExecuteButtonPress(bool is_error_page, Button button) {
- // UMA to investigate http://crbug.com/500556.
- // TODO(mmenke): Remove when the issue is fixed.
- int button_press_info = 0;
- if (!is_error_page)
- button_press_info |= ERROR_PAGE_BUTTON_PRESS_FOR_NON_ERROR_PAGE_URL;
- if (!committed_error_page_info_)
- button_press_info |= ERROR_PAGE_BUTTON_PRESS_WITH_NO_ERROR_INFO;
- UMA_HISTOGRAM_ENUMERATION("Net.ErrorPageButtonPressUnexpectedStates",
- button_press_info,
- ERROR_PAGE_BUTTON_PRESS_MAX);
- if (button_press_info != 0) {
- UMA_HISTOGRAM_ENUMERATION(
- "Net.ErrorPageButtonPressedWhileInUnexpectedState",
- button, BUTTON_MAX);
- }
-
- // Unclear why this happens.
- // TODO(mmenke): Remove when http://crbug.com/500556 is fixed.
- if (!committed_error_page_info_)
- return;
+void NetErrorHelperCore::ExecuteButtonPress(Button button) {
+ // If there's no committed error page, should not be invoked.
+ DCHECK(committed_error_page_info_);
switch (button) {
case RELOAD_BUTTON:
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_RELOAD_BUTTON_CLICKED);
+ RecordEvent(NETWORK_ERROR_PAGE_RELOAD_BUTTON_CLICKED);
if (committed_error_page_info_->show_saved_copy_button_in_page) {
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_BOTH_BUTTONS_RELOAD_CLICKED);
+ RecordEvent(NETWORK_ERROR_PAGE_BOTH_BUTTONS_RELOAD_CLICKED);
}
navigation_from_button_ = RELOAD_BUTTON;
Reload();
return;
case SHOW_SAVED_COPY_BUTTON:
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_CLICKED);
+ RecordEvent(NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_CLICKED);
navigation_from_button_ = SHOW_SAVED_COPY_BUTTON;
if (committed_error_page_info_->reload_button_in_page) {
- chrome_common_net::RecordEvent(chrome_common_net::
- NETWORK_ERROR_PAGE_BOTH_BUTTONS_SHOWN_SAVED_COPY_CLICKED);
+ RecordEvent(NETWORK_ERROR_PAGE_BOTH_BUTTONS_SHOWN_SAVED_COPY_CLICKED);
}
delegate_->LoadPageFromCache(
committed_error_page_info_->error.unreachableURL);
return;
case MORE_BUTTON:
// Visual effects on page are handled in Javascript code.
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_MORE_BUTTON_CLICKED);
+ RecordEvent(NETWORK_ERROR_PAGE_MORE_BUTTON_CLICKED);
return;
case EASTER_EGG:
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_EASTER_EGG_ACTIVATED);
+ RecordEvent(NETWORK_ERROR_EASTER_EGG_ACTIVATED);
return;
case SHOW_CACHED_COPY_BUTTON:
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_CACHED_COPY_BUTTON_CLICKED);
+ RecordEvent(NETWORK_ERROR_PAGE_CACHED_COPY_BUTTON_CLICKED);
return;
- case SHOW_CACHED_PAGE_BUTTON:
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_CACHED_PAGE_BUTTON_CLICKED);
+ case DIAGNOSE_ERROR:
+ RecordEvent(NETWORK_ERROR_DIAGNOSE_BUTTON_CLICKED);
+ delegate_->DiagnoseError(
+ committed_error_page_info_->error.unreachableURL);
return;
- case BUTTON_MAX:
case NO_BUTTON:
NOTREACHED();
return;
diff --git a/chromium/components/error_page/renderer/net_error_helper_core.h b/chromium/components/error_page/renderer/net_error_helper_core.h
index 7f7fafb6ceb..be88ccc80d2 100644
--- a/chromium/components/error_page/renderer/net_error_helper_core.h
+++ b/chromium/components/error_page/renderer/net_error_helper_core.h
@@ -49,8 +49,7 @@ class NetErrorHelperCore {
MORE_BUTTON,
EASTER_EGG,
SHOW_CACHED_COPY_BUTTON, // "Google cached copy" button label experiment.
- SHOW_CACHED_PAGE_BUTTON, // "Google cached page" button label experiment.
- BUTTON_MAX,
+ DIAGNOSE_ERROR,
};
// The Delegate handles all interaction with the RenderView, WebFrame, and
@@ -61,25 +60,27 @@ class NetErrorHelperCore {
virtual void GenerateLocalizedErrorPage(
const blink::WebURLError& error,
bool is_failed_post,
- scoped_ptr<error_page::ErrorPageParams> params,
+ bool can_show_network_diagnostics_dialog,
+ scoped_ptr<ErrorPageParams> params,
bool* reload_button_shown,
bool* show_saved_copy_button_shown,
bool* show_cached_copy_button_shown,
- bool* show_cached_page_button_shown,
std::string* html) const = 0;
// Loads the given HTML in the main frame for use as an error page.
virtual void LoadErrorPageInMainFrame(const std::string& html,
const GURL& failed_url) = 0;
- // Create extra Javascript bindings in the error page.
+ // Create extra Javascript bindings in the error page. Will only be invoked
+ // after an error page has finished loading.
virtual void EnablePageHelperFunctions() = 0;
// Updates the currently displayed error page with a new error code. The
// currently displayed error page must have finished loading, and must have
// been generated by a call to GenerateLocalizedErrorPage.
virtual void UpdateErrorPage(const blink::WebURLError& error,
- bool is_failed_post) = 0;
+ bool is_failed_post,
+ bool can_show_network_diagnostics_dialog) = 0;
// Fetches an error page and calls into OnErrorPageFetched when done. Any
// previous fetch must either be canceled or finished before calling. Can't
@@ -104,6 +105,9 @@ class NetErrorHelperCore {
// Load the original page from cache.
virtual void LoadPageFromCache(const GURL& page_url) = 0;
+ // Run the platform diagnostics too for the specified URL.
+ virtual void DiagnoseError(const GURL& page_url) = 0;
+
protected:
virtual ~Delegate() {}
};
@@ -158,7 +162,12 @@ class NetErrorHelperCore {
// Notifies |this| that network error information from the browser process
// has been received.
- void OnNetErrorInfo(chrome_common_net::DnsProbeStatus status);
+ void OnNetErrorInfo(DnsProbeStatus status);
+
+ // Notifies |this| if it can use a local error diagnostics service through its
+ // delegate.
+ void OnSetCanShowNetworkDiagnosticsDialog(
+ bool can_show_network_diagnostics_dialog);
void OnSetNavigationCorrectionInfo(const GURL& navigation_correction_url,
const std::string& language,
@@ -189,11 +198,7 @@ class NetErrorHelperCore {
// Execute the effect of pressing the specified button.
// Note that the visual effects of the 'MORE' button are taken
// care of in JavaScript.
- //
- // |is_error_page| indicates if the button press came from an actual error
- // page or some other source. It should always be true, but may not be.
- // Included as part of an investigation into http://crbug.com/500556.
- void ExecuteButtonPress(bool is_error_page, Button button);
+ void ExecuteButtonPress(Button button);
// Reports to the correction service that the link with the given tracking
// ID was clicked. Only pages generated with information from the service
@@ -228,7 +233,7 @@ class NetErrorHelperCore {
Delegate* delegate_;
// The last DnsProbeStatus received from the browser.
- chrome_common_net::DnsProbeStatus last_probe_status_;
+ DnsProbeStatus last_probe_status_;
// Information for the provisional / "pre-provisional" error page. NULL when
// there's no page pending, or the pending page is not an error page.
@@ -238,6 +243,8 @@ class NetErrorHelperCore {
// not an error page.
scoped_ptr<ErrorPageInfo> committed_error_page_info_;
+ bool can_show_network_diagnostics_dialog_;
+
NavigationCorrectionParams navigation_correction_params_;
// True if auto-reload is enabled at all.
diff --git a/chromium/components/error_page/renderer/net_error_helper_core_unittest.cc b/chromium/components/error_page/renderer/net_error_helper_core_unittest.cc
index 1284def6d7a..20ccb91ab22 100644
--- a/chromium/components/error_page/renderer/net_error_helper_core_unittest.cc
+++ b/chromium/components/error_page/renderer/net_error_helper_core_unittest.cc
@@ -19,6 +19,7 @@
#include "base/values.h"
#include "components/error_page/common/error_page_params.h"
#include "components/error_page/common/net_error_info.h"
+#include "components/test_runner/test_common.h"
#include "content/public/common/url_constants.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -29,9 +30,6 @@ namespace error_page {
namespace {
using blink::WebURLError;
-using chrome_common_net::DnsProbeStatus;
-using chrome_common_net::DnsProbeStatusToString;
-using error_page::ErrorPageParams;
const char kFailedUrl[] = "http://failed/";
const char kFailedHttpsUrl[] = "https://failed/";
@@ -120,8 +118,7 @@ std::string ErrorToString(const WebURLError& error, bool is_failed_post) {
WebURLError ProbeError(DnsProbeStatus status) {
WebURLError error;
error.unreachableURL = GURL(kFailedUrl);
- error.domain = blink::WebString::fromUTF8(
- chrome_common_net::kDnsProbeErrorDomain);
+ error.domain = blink::WebString::fromUTF8(kDnsProbeErrorDomain);
error.reason = status;
return error;
}
@@ -160,11 +157,13 @@ class NetErrorHelperCoreTest : public testing::Test,
error_html_update_count_(0),
reload_count_(0),
show_saved_count_(0),
+ diagnose_error_count_(0),
enable_page_helper_functions_count_(0),
default_url_(GURL(kFailedUrl)),
error_url_(GURL(content::kUnreachableWebDataURL)),
tracking_request_count_(0) {
SetUpCore(false, false, true);
+ test_runner::EnsureBlinkInitialized();
}
~NetErrorHelperCoreTest() override {
@@ -204,6 +203,14 @@ class NetErrorHelperCoreTest : public testing::Test,
return show_saved_url_;
}
+ int diagnose_error_count() const {
+ return diagnose_error_count_;
+ }
+
+ const GURL& diagnose_error_url() const {
+ return diagnose_error_url_;
+ }
+
const GURL& default_url() const {
return default_url_;
}
@@ -222,6 +229,10 @@ class NetErrorHelperCoreTest : public testing::Test,
const std::string& last_error_html() const { return last_error_html_; }
int error_html_update_count() const { return error_html_update_count_; }
+ bool last_can_show_network_diagnostics_dialog() const {
+ return last_can_show_network_diagnostics_dialog_;
+ }
+
const ErrorPageParams* last_error_page_params() const {
return last_error_page_params_.get();
}
@@ -251,17 +262,17 @@ class NetErrorHelperCoreTest : public testing::Test,
void DoErrorLoadOfURL(net::Error error, const GURL& url) {
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetErrorForURL(error, url), false, &html);
+ NetErrorForURL(error, url), false, &html);
EXPECT_FALSE(html.empty());
EXPECT_EQ(NetErrorStringForURL(error, url), html);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME,
- error_url());
+ error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
}
@@ -271,13 +282,13 @@ class NetErrorHelperCoreTest : public testing::Test,
void DoSuccessLoad() {
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, default_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
}
- void DoDnsProbe(chrome_common_net::DnsProbeStatus final_status) {
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
+ void DoDnsProbe(DnsProbeStatus final_status) {
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
core()->OnNetErrorInfo(final_status);
}
@@ -301,24 +312,25 @@ class NetErrorHelperCoreTest : public testing::Test,
private:
void SetNavigationCorrectionURL(const GURL& navigation_correction_url) {
core()->OnSetNavigationCorrectionInfo(navigation_correction_url,
- kLanguage, kCountry, kApiKey,
- GURL(kSearchUrl));
+ kLanguage, kCountry, kApiKey,
+ GURL(kSearchUrl));
}
// NetErrorHelperCore::Delegate implementation:
void GenerateLocalizedErrorPage(const WebURLError& error,
bool is_failed_post,
+ bool can_show_network_diagnostics_dialog,
scoped_ptr<ErrorPageParams> params,
bool* reload_button_shown,
bool* show_saved_copy_button_shown,
bool* show_cached_copy_button_shown,
- bool* show_cached_page_button_shown,
std::string* html) const override {
+ last_can_show_network_diagnostics_dialog_ =
+ can_show_network_diagnostics_dialog;
last_error_page_params_.reset(params.release());
*reload_button_shown = false;
*show_saved_copy_button_shown = false;
*show_cached_copy_button_shown = false;
- *show_cached_page_button_shown = false;
*html = ErrorToString(error, is_failed_post);
}
@@ -332,9 +344,12 @@ class NetErrorHelperCoreTest : public testing::Test,
enable_page_helper_functions_count_++;
}
- void UpdateErrorPage(const WebURLError& error, bool is_failed_post) override {
+ void UpdateErrorPage(const WebURLError& error, bool is_failed_post,
+ bool can_show_network_diagnostics_dialog) override {
update_count_++;
- last_error_page_params_.reset(NULL);
+ last_can_show_network_diagnostics_dialog_ =
+ can_show_network_diagnostics_dialog;
+ last_error_page_params_.reset(nullptr);
last_error_html_ = ErrorToString(error, is_failed_post);
}
@@ -370,9 +385,14 @@ class NetErrorHelperCoreTest : public testing::Test,
void ReloadPage() override { reload_count_++; }
- void LoadPageFromCache(const GURL& error_url) override {
+ void LoadPageFromCache(const GURL& page_url) override {
show_saved_count_++;
- show_saved_url_ = error_url;
+ show_saved_url_ = page_url;
+ }
+
+ void DiagnoseError(const GURL& page_url) override {
+ diagnose_error_count_++;
+ diagnose_error_url_ = page_url;
}
void SendTrackingRequest(const GURL& tracking_url,
@@ -414,12 +434,17 @@ class NetErrorHelperCoreTest : public testing::Test,
// Number of times |last_error_html_| has been changed.
int error_html_update_count_;
- // Mutable because GenerateLocalizedErrorPage is const.
+ // Values passed in to the last call of GenerateLocalizedErrorPage or
+ // UpdateErrorPage. Mutable because GenerateLocalizedErrorPage is const.
+ mutable bool last_can_show_network_diagnostics_dialog_;
mutable scoped_ptr<ErrorPageParams> last_error_page_params_;
int reload_count_;
int show_saved_count_;
GURL show_saved_url_;
+ int diagnose_error_count_;
+ GURL diagnose_error_url_;
+
int enable_page_helper_functions_count_;
@@ -441,7 +466,7 @@ TEST_F(NetErrorHelperCoreTest, Null) {
TEST_F(NetErrorHelperCoreTest, SuccessfulPageLoad) {
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, default_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(0, update_count());
@@ -451,7 +476,7 @@ TEST_F(NetErrorHelperCoreTest, SuccessfulPageLoad) {
TEST_F(NetErrorHelperCoreTest, SuccessfulPageLoadWithNavigationCorrections) {
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, default_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(0, update_count());
@@ -461,12 +486,12 @@ TEST_F(NetErrorHelperCoreTest, SuccessfulPageLoadWithNavigationCorrections) {
TEST_F(NetErrorHelperCoreTest, MainFrameNonDnsError) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_RESET), false, &html);
+ NetError(net::ERR_CONNECTION_RESET), false, &html);
// Should have returned a local error page.
EXPECT_FALSE(html.empty());
EXPECT_EQ(NetErrorString(net::ERR_CONNECTION_RESET), html);
@@ -474,7 +499,7 @@ TEST_F(NetErrorHelperCoreTest, MainFrameNonDnsError) {
// Error page loads.
EXPECT_EQ(0, enable_page_helper_functions_count());
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(0, update_count());
@@ -487,19 +512,19 @@ TEST_F(NetErrorHelperCoreTest, MainFrameNonDnsErrorWithCorrections) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_RESET), false, &html);
+ NetError(net::ERR_CONNECTION_RESET), false, &html);
// Should have returned a local error page.
EXPECT_FALSE(html.empty());
EXPECT_EQ(NetErrorString(net::ERR_CONNECTION_RESET), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(0, update_count());
@@ -511,15 +536,15 @@ TEST_F(NetErrorHelperCoreTest, MainFrameNonDnsErrorWithCorrections) {
TEST_F(NetErrorHelperCoreTest, MainFrameNonDnsErrorSpuriousStatus) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ NetErrorHelperCore::NON_ERROR_PAGE);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_RESET),
- false, &html);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ NetError(net::ERR_CONNECTION_RESET),
+ false, &html);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
// Should have returned a local error page.
EXPECT_FALSE(html.empty());
@@ -528,14 +553,14 @@ TEST_F(NetErrorHelperCoreTest, MainFrameNonDnsErrorSpuriousStatus) {
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ NetErrorHelperCore::ERROR_PAGE);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
EXPECT_EQ(0, error_html_update_count());
@@ -544,19 +569,19 @@ TEST_F(NetErrorHelperCoreTest, MainFrameNonDnsErrorSpuriousStatus) {
TEST_F(NetErrorHelperCoreTest, SubFrameDnsError) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::SUB_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::SUB_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page.
EXPECT_EQ(NetErrorString(net::ERR_NAME_NOT_RESOLVED), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::SUB_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::SUB_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::SUB_FRAME);
EXPECT_EQ(0, update_count());
@@ -568,19 +593,19 @@ TEST_F(NetErrorHelperCoreTest, SubFrameDnsErrorWithCorrections) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::SUB_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::SUB_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page.
EXPECT_EQ(NetErrorString(net::ERR_NAME_NOT_RESOLVED), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::SUB_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::SUB_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::SUB_FRAME);
EXPECT_EQ(0, update_count());
@@ -592,15 +617,15 @@ TEST_F(NetErrorHelperCoreTest, SubFrameDnsErrorWithCorrections) {
TEST_F(NetErrorHelperCoreTest, SubFrameDnsErrorSpuriousStatus) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::SUB_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ NetErrorHelperCore::NON_ERROR_PAGE);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::SUB_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
// Should have returned a local error page.
EXPECT_EQ(NetErrorString(net::ERR_NAME_NOT_RESOLVED), html);
@@ -608,14 +633,14 @@ TEST_F(NetErrorHelperCoreTest, SubFrameDnsErrorSpuriousStatus) {
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::SUB_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ NetErrorHelperCore::ERROR_PAGE);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
core()->OnCommitLoad(NetErrorHelperCore::SUB_FRAME, error_url());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
core()->OnFinishLoad(NetErrorHelperCore::SUB_FRAME);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
EXPECT_EQ(0, error_html_update_count());
@@ -631,36 +656,34 @@ TEST_F(NetErrorHelperCoreTest, SubFrameDnsErrorSpuriousStatus) {
TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbe) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(0, update_count());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
EXPECT_EQ(1, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_STARTED),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_STARTED), last_error_html());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(2, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NXDOMAIN), last_error_html());
// Any other probe updates should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(2, update_count());
EXPECT_EQ(0, error_html_update_count());
}
@@ -669,32 +692,32 @@ TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbe) {
TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbeNotRun) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(0, update_count());
// When the not run status arrives, the page should revert to the normal dns
// error page.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_NOT_RUN);
+ core()->OnNetErrorInfo(DNS_PROBE_NOT_RUN);
EXPECT_EQ(1, update_count());
EXPECT_EQ(NetErrorString(net::ERR_NAME_NOT_RESOLVED), last_error_html());
// Any other probe updates should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(1, update_count());
EXPECT_EQ(0, error_html_update_count());
}
@@ -703,36 +726,35 @@ TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbeNotRun) {
TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbeInconclusive) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(0, update_count());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
EXPECT_EQ(1, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_STARTED),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_STARTED), last_error_html());
// When the inconclusive status arrives, the page should revert to the normal
// dns error page.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_INCONCLUSIVE);
EXPECT_EQ(2, update_count());
EXPECT_EQ(NetErrorString(net::ERR_NAME_NOT_RESOLVED), last_error_html());
// Any other probe updates should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_INCONCLUSIVE);
EXPECT_EQ(2, update_count());
EXPECT_EQ(0, error_html_update_count());
}
@@ -741,37 +763,36 @@ TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbeInconclusive) {
TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbeNoInternet) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(0, update_count());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
EXPECT_EQ(1, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_STARTED),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_STARTED), last_error_html());
// When the inconclusive status arrives, the page should revert to the normal
// dns error page.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NO_INTERNET);
EXPECT_EQ(2, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET),
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NO_INTERNET),
last_error_html());
// Any other probe updates should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NO_INTERNET);
EXPECT_EQ(2, update_count());
EXPECT_EQ(0, error_html_update_count());
}
@@ -780,37 +801,35 @@ TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbeNoInternet) {
TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbeBadConfig) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(0, update_count());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
EXPECT_EQ(1, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_STARTED),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_STARTED), last_error_html());
// When the inconclusive status arrives, the page should revert to the normal
// dns error page.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_BAD_CONFIG);
EXPECT_EQ(2, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_BAD_CONFIG), last_error_html());
// Any other probe updates should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_BAD_CONFIG);
EXPECT_EQ(2, update_count());
EXPECT_EQ(0, error_html_update_count());
}
@@ -820,41 +839,39 @@ TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbeBadConfig) {
TEST_F(NetErrorHelperCoreTest, FinishedAfterStartProbe) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
// Nothing should be done when a probe status comes in before loading
// finishes.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
EXPECT_EQ(0, update_count());
// When loading finishes, however, the buffered probe status should be sent
// to the page.
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(1, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_STARTED),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_STARTED), last_error_html());
// Should update the page again when the probe result comes in.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(2, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NXDOMAIN), last_error_html());
// Any other probe updates should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_NOT_RUN);
+ core()->OnNetErrorInfo(DNS_PROBE_NOT_RUN);
EXPECT_EQ(2, update_count());
}
@@ -863,39 +880,33 @@ TEST_F(NetErrorHelperCoreTest, FinishedAfterStartProbe) {
TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbePost) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- true, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ true, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ErrorToString(
- ProbeError(chrome_common_net::DNS_PROBE_POSSIBLE),
- true),
- html);
+ EXPECT_EQ(ErrorToString(ProbeError(DNS_PROBE_POSSIBLE), true), html);
// Error page loads.
EXPECT_EQ(0, enable_page_helper_functions_count());
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(0, update_count());
EXPECT_EQ(1, enable_page_helper_functions_count());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
EXPECT_EQ(1, update_count());
- EXPECT_EQ(ErrorToString(
- ProbeError(chrome_common_net::DNS_PROBE_STARTED), true),
+ EXPECT_EQ(ErrorToString(ProbeError(DNS_PROBE_STARTED), true),
last_error_html());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(2, update_count());
- EXPECT_EQ(ErrorToString(
- ProbeError(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN),
- true),
+ EXPECT_EQ(ErrorToString(ProbeError(DNS_PROBE_FINISHED_NXDOMAIN), true),
last_error_html());
EXPECT_EQ(0, error_html_update_count());
}
@@ -904,24 +915,24 @@ TEST_F(NetErrorHelperCoreTest, FinishedBeforeProbePost) {
TEST_F(NetErrorHelperCoreTest, ProbeFinishesEarly) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
// Nothing should be done when the probe statuses come in before loading
// finishes.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
@@ -931,12 +942,11 @@ TEST_F(NetErrorHelperCoreTest, ProbeFinishesEarly) {
// to the page.
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(1, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NXDOMAIN), last_error_html());
// Any other probe updates should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(1, update_count());
}
@@ -945,58 +955,56 @@ TEST_F(NetErrorHelperCoreTest, ProbeFinishesEarly) {
TEST_F(NetErrorHelperCoreTest, TwoErrorsWithProbes) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
// Probe results come in.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(2, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NXDOMAIN), last_error_html());
// The process starts again.
// Normal page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(2, update_count());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
EXPECT_EQ(3, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_STARTED),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_STARTED), last_error_html());
// The probe returns a different result this time.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NO_INTERNET);
EXPECT_EQ(4, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET),
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NO_INTERNET),
last_error_html());
EXPECT_EQ(0, error_html_update_count());
}
@@ -1007,19 +1015,19 @@ TEST_F(NetErrorHelperCoreTest, TwoErrorsWithProbes) {
TEST_F(NetErrorHelperCoreTest, TwoErrorsWithProbesAfterSecondStarts) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
@@ -1027,35 +1035,33 @@ TEST_F(NetErrorHelperCoreTest, TwoErrorsWithProbesAfterSecondStarts) {
// Normal page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page starts to load.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
// Probe results come in, and the first page is updated.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(2, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NXDOMAIN), last_error_html());
// Second page finishes loading, and is updated using the same probe result.
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(3, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NXDOMAIN), last_error_html());
// Other probe results should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NO_INTERNET);
EXPECT_EQ(3, update_count());
EXPECT_EQ(0, error_html_update_count());
}
@@ -1064,48 +1070,48 @@ TEST_F(NetErrorHelperCoreTest, TwoErrorsWithProbesAfterSecondStarts) {
TEST_F(NetErrorHelperCoreTest, ErrorPageLoadInterrupted) {
// Original page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and an error page is requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
// Probe statuses come in, but should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
// A new navigation begins while the error page is loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// And fails.
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
// Should have returned a local error page indicating a probe may run.
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE), html);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_POSSIBLE), html);
// Error page finishes loading.
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
// Probe results come in.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
EXPECT_EQ(1, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_STARTED),
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_STARTED),
last_error_html());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NO_INTERNET);
EXPECT_EQ(2, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET),
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NO_INTERNET),
last_error_html());
EXPECT_EQ(0, error_html_update_count());
}
@@ -1119,7 +1125,7 @@ TEST_F(NetErrorHelperCoreTest, NoCorrectionsForHttps) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// The HTTPS page fails to load.
std::string html;
@@ -1127,8 +1133,7 @@ TEST_F(NetErrorHelperCoreTest, NoCorrectionsForHttps) {
error.unreachableURL = GURL(kFailedHttpsUrl);
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME, error, false, &html);
- blink::WebURLError probe_error =
- ProbeError(chrome_common_net::DNS_PROBE_POSSIBLE);
+ blink::WebURLError probe_error = ProbeError(DNS_PROBE_POSSIBLE);
probe_error.unreachableURL = GURL(kFailedHttpsUrl);
EXPECT_EQ(ErrorToString(probe_error, false), html);
EXPECT_FALSE(is_url_being_fetched());
@@ -1136,7 +1141,7 @@ TEST_F(NetErrorHelperCoreTest, NoCorrectionsForHttps) {
// The blank page loads, no error page is loaded.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_FALSE(is_url_being_fetched());
@@ -1144,12 +1149,12 @@ TEST_F(NetErrorHelperCoreTest, NoCorrectionsForHttps) {
// Page is updated in response to DNS probes as normal.
EXPECT_EQ(0, update_count());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(2, update_count());
EXPECT_FALSE(last_error_page_params());
blink::WebURLError final_probe_error =
- ProbeError(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ ProbeError(DNS_PROBE_FINISHED_NXDOMAIN);
final_probe_error.unreachableURL = GURL(kFailedHttpsUrl);
EXPECT_EQ(ErrorToString(final_probe_error, false), last_error_html());
}
@@ -1160,13 +1165,13 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsReceivedBeforeProbe) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
EXPECT_FALSE(is_url_being_fetched());
EXPECT_FALSE(last_error_page_params());
@@ -1198,8 +1203,8 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsReceivedBeforeProbe) {
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
// Any probe statuses should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
EXPECT_EQ(1, error_html_update_count());
@@ -1211,26 +1216,26 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsRetrievedAfterProbes) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_TRUE(is_url_being_fetched());
EXPECT_FALSE(last_error_page_params());
// Probe statuses should be ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
EXPECT_EQ(0, error_html_update_count());
EXPECT_FALSE(last_error_page_params());
@@ -1246,7 +1251,7 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsRetrievedAfterProbes) {
// Corrections load.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(1, error_html_update_count());
@@ -1259,18 +1264,18 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsFailLoadNoProbes) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_FAILED),
- false, &html);
+ NetError(net::ERR_CONNECTION_FAILED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
@@ -1285,14 +1290,14 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsFailLoadNoProbes) {
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
// If probe statuses come in last from another page load, they should be
// ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
EXPECT_EQ(1, error_html_update_count());
}
@@ -1303,18 +1308,18 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsFailLoadBeforeProbe) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
@@ -1323,29 +1328,27 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsFailLoadBeforeProbe) {
NavigationCorrectionsLoadFailure();
EXPECT_EQ(1, error_html_update_count());
EXPECT_EQ(last_error_html(),
- ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE));
+ ProbeErrorString(DNS_PROBE_POSSIBLE));
EXPECT_FALSE(is_url_being_fetched());
EXPECT_EQ(0, update_count());
// Probe page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
// Probe statuses comes in, and page is updated.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
EXPECT_EQ(1, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_STARTED),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_STARTED), last_error_html());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(2, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NXDOMAIN), last_error_html());
// The commit results in sending a second probe status, which is ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(2, update_count());
EXPECT_EQ(1, error_html_update_count());
}
@@ -1355,46 +1358,44 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsFailAfterProbe) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
// Results come in, but end up being ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
// Corrections request fails, probe pending page shown.
EXPECT_TRUE(is_url_being_fetched());
NavigationCorrectionsLoadFailure();
EXPECT_EQ(1, error_html_update_count());
- EXPECT_EQ(last_error_html(),
- ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE));
+ EXPECT_EQ(last_error_html(), ProbeErrorString(DNS_PROBE_POSSIBLE));
EXPECT_FALSE(is_url_being_fetched());
EXPECT_EQ(0, update_count());
// Probe page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
// Probe statuses comes in, and page is updated.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(1, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NXDOMAIN), last_error_html());
EXPECT_EQ(1, error_html_update_count());
}
@@ -1404,28 +1405,28 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsInterruptedBeforeCommit) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page starts loading.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
// A new page load starts.
EXPECT_FALSE(is_url_being_fetched());
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// A new page load interrupts the original load.
EXPECT_FALSE(is_url_being_fetched());
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
EXPECT_FALSE(is_url_being_fetched());
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, default_url());
EXPECT_FALSE(is_url_being_fetched());
@@ -1442,24 +1443,24 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsInterruptedBeforeLoad) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page starts loading and is committed.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
// A new page load interrupts the original load.
EXPECT_FALSE(is_url_being_fetched());
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
EXPECT_FALSE(is_url_being_fetched());
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, default_url());
EXPECT_FALSE(is_url_being_fetched());
@@ -1476,39 +1477,39 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsInterrupted) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_TRUE(is_url_being_fetched());
// Results come in, but end up being ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
// A new load appears!
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
EXPECT_FALSE(is_url_being_fetched());
// It fails, and corrections are requested again once a blank page is loaded.
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
EXPECT_FALSE(is_url_being_fetched());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
@@ -1523,8 +1524,8 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsInterrupted) {
EXPECT_FALSE(is_url_being_fetched());
// Probe statuses come in, and are ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
}
@@ -1535,18 +1536,18 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsStopped) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
@@ -1555,23 +1556,23 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsStopped) {
EXPECT_FALSE(is_url_being_fetched());
// Results come in, but end up being ignored.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(0, update_count());
// Cross process navigation must have been cancelled, and a new load appears!
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested again.
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads again.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_TRUE(is_url_being_fetched());
@@ -1579,26 +1580,23 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsStopped) {
// Corrections request fails, probe pending page shown.
NavigationCorrectionsLoadFailure();
EXPECT_EQ(1, error_html_update_count());
- EXPECT_EQ(last_error_html(),
- ProbeErrorString(chrome_common_net::DNS_PROBE_POSSIBLE));
+ EXPECT_EQ(last_error_html(), ProbeErrorString(DNS_PROBE_POSSIBLE));
EXPECT_FALSE(is_url_being_fetched());
// Probe page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
// Probe statuses comes in, and page is updated.
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_STARTED);
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_STARTED),
- last_error_html());
+ core()->OnNetErrorInfo(DNS_PROBE_STARTED);
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_STARTED), last_error_html());
EXPECT_EQ(1, update_count());
- core()->OnNetErrorInfo(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ core()->OnNetErrorInfo(DNS_PROBE_FINISHED_NXDOMAIN);
EXPECT_EQ(2, update_count());
- EXPECT_EQ(ProbeErrorString(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN),
- last_error_html());
+ EXPECT_EQ(ProbeErrorString(DNS_PROBE_FINISHED_NXDOMAIN), last_error_html());
EXPECT_EQ(1, error_html_update_count());
}
@@ -1608,18 +1606,18 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsDisabledBeforeFetch) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
// Corrections is disabled.
DisableNavigationCorrections();
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
@@ -1637,7 +1635,7 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsDisabledBeforeFetch) {
// Corrections load.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(1, error_html_update_count());
@@ -1650,18 +1648,18 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsDisabledDuringFetch) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_TRUE(is_url_being_fetched());
@@ -1680,7 +1678,7 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsDisabledDuringFetch) {
// Corrections load.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(1, error_html_update_count());
@@ -1696,18 +1694,18 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsWithoutSearch) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_TRUE(is_url_being_fetched());
@@ -1728,7 +1726,7 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsWithoutSearch) {
// Corrections load.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(1, error_html_update_count());
@@ -1744,18 +1742,18 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsOnlySearchSuggestion) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_TRUE(is_url_being_fetched());
@@ -1776,7 +1774,7 @@ TEST_F(NetErrorHelperCoreTest, CorrectionsOnlySearchSuggestion) {
// Corrections load.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
EXPECT_EQ(1, error_html_update_count());
@@ -1788,18 +1786,18 @@ TEST_F(NetErrorHelperCoreTest, CorrectionServiceReturnsNonJsonResult) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_FAILED),
- false, &html);
+ NetError(net::ERR_CONNECTION_FAILED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
@@ -1814,7 +1812,7 @@ TEST_F(NetErrorHelperCoreTest, CorrectionServiceReturnsNonJsonResult) {
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
}
@@ -1825,18 +1823,18 @@ TEST_F(NetErrorHelperCoreTest, CorrectionServiceReturnsInvalidJsonResult) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails, and corrections are requested.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_FAILED),
- false, &html);
+ NetError(net::ERR_CONNECTION_FAILED),
+ false, &html);
EXPECT_TRUE(html.empty());
// The blank page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
@@ -1851,7 +1849,7 @@ TEST_F(NetErrorHelperCoreTest, CorrectionServiceReturnsInvalidJsonResult) {
// Error page loads.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
}
@@ -1862,13 +1860,13 @@ TEST_F(NetErrorHelperCoreTest, CorrectionClickTracking) {
// Original page starts loading.
EnableNavigationCorrections();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// It fails.
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_NAME_NOT_RESOLVED),
- false, &html);
+ NetError(net::ERR_NAME_NOT_RESOLVED),
+ false, &html);
EXPECT_TRUE(html.empty());
EXPECT_FALSE(is_url_being_fetched());
EXPECT_FALSE(last_error_page_params());
@@ -1918,15 +1916,15 @@ TEST_F(NetErrorHelperCoreTest, CorrectionClickTracking) {
// Make sure all expected strings appear in output.
EXPECT_TRUE(last_tracking_request_body().find(
- kDefaultCorrections[i].url_correction));
+ kDefaultCorrections[i].url_correction));
EXPECT_TRUE(last_tracking_request_body().find(
- kDefaultCorrections[i].click_data));
+ kDefaultCorrections[i].click_data));
EXPECT_TRUE(last_tracking_request_body().find(
- kDefaultCorrections[i].click_type));
+ kDefaultCorrections[i].click_type));
EXPECT_TRUE(last_tracking_request_body().find(
- kNavigationCorrectionEventId));
+ kNavigationCorrectionEventId));
EXPECT_TRUE(last_tracking_request_body().find(
- kNavigationCorrectionFingerprint));
+ kNavigationCorrectionFingerprint));
}
// Make sure duplicate tracking requests are ignored.
@@ -2013,7 +2011,7 @@ TEST_F(NetErrorHelperCoreAutoReloadTest, StopsOnOtherLoadStart) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
EXPECT_TRUE(timer()->IsRunning());
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
EXPECT_FALSE(timer()->IsRunning());
EXPECT_EQ(0, core()->auto_reload_count());
}
@@ -2077,7 +2075,7 @@ TEST_F(NetErrorHelperCoreAutoReloadTest, DoesNotRestartOnOnlineAfterStop) {
TEST_F(NetErrorHelperCoreAutoReloadTest, WithDnsProbes) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
- DoDnsProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+ DoDnsProbe(DNS_PROBE_FINISHED_NXDOMAIN);
timer()->Fire();
EXPECT_EQ(1, reload_count());
}
@@ -2100,17 +2098,17 @@ TEST_F(NetErrorHelperCoreAutoReloadTest, ExponentialBackoffLevelsOff) {
TEST_F(NetErrorHelperCoreAutoReloadTest, SlowError) {
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_RESET), false, &html);
+ NetError(net::ERR_CONNECTION_RESET), false, &html);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
EXPECT_FALSE(timer()->IsRunning());
// Start a new non-error page load.
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
EXPECT_FALSE(timer()->IsRunning());
// Finish the error page load.
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
@@ -2123,12 +2121,12 @@ TEST_F(NetErrorHelperCoreAutoReloadTest, SlowError) {
TEST_F(NetErrorHelperCoreAutoReloadTest, OnlineSlowError) {
core()->NetworkStateChanged(false);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_RESET), false, &html);
+ NetError(net::ERR_CONNECTION_RESET), false, &html);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
EXPECT_FALSE(timer()->IsRunning());
core()->NetworkStateChanged(true);
@@ -2143,12 +2141,12 @@ TEST_F(NetErrorHelperCoreAutoReloadTest, OnlineSlowError) {
TEST_F(NetErrorHelperCoreAutoReloadTest, OnlinePendingError) {
core()->NetworkStateChanged(false);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_RESET), false, &html);
+ NetError(net::ERR_CONNECTION_RESET), false, &html);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
EXPECT_FALSE(timer()->IsRunning());
core()->NetworkStateChanged(true);
EXPECT_FALSE(timer()->IsRunning());
@@ -2163,20 +2161,20 @@ TEST_F(NetErrorHelperCoreAutoReloadTest, OnlinePendingError) {
TEST_F(NetErrorHelperCoreAutoReloadTest, OnlinePartialErrorReplacement) {
core()->NetworkStateChanged(false);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
std::string html;
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_RESET), false, &html);
+ NetError(net::ERR_CONNECTION_RESET), false, &html);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
core()->GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
- NetError(net::ERR_CONNECTION_RESET), false, &html);
+ NetError(net::ERR_CONNECTION_RESET), false, &html);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::ERROR_PAGE);
+ NetErrorHelperCore::ERROR_PAGE);
EXPECT_FALSE(timer()->IsRunning());
core()->NetworkStateChanged(true);
EXPECT_FALSE(timer()->IsRunning());
@@ -2220,7 +2218,7 @@ TEST_F(NetErrorHelperCoreAutoReloadTest, ShouldSuppressErrorPage) {
// Sub-frame load.
EXPECT_FALSE(core()->ShouldSuppressErrorPage(NetErrorHelperCore::SUB_FRAME,
- GURL(kFailedUrl)));
+ GURL(kFailedUrl)));
EXPECT_TRUE(core()->ShouldSuppressErrorPage(NetErrorHelperCore::MAIN_FRAME,
GURL(kFailedUrl)));
// No auto-reload attempt in flight.
@@ -2326,7 +2324,7 @@ TEST_F(NetErrorHelperCoreHistogramTest, SuccessAtSecondAttempt) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
timer()->Fire();
EXPECT_TRUE(core()->ShouldSuppressErrorPage(NetErrorHelperCore::MAIN_FRAME,
- default_url()));
+ default_url()));
timer()->Fire();
DoSuccessLoad();
@@ -2347,7 +2345,7 @@ TEST_F(NetErrorHelperCoreHistogramTest, UserStop) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
timer()->Fire();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
core()->OnStop();
// CountAtStop and ErrorAtStop should reflect the failure.
@@ -2366,7 +2364,7 @@ TEST_F(NetErrorHelperCoreHistogramTest, UserStop) {
TEST_F(NetErrorHelperCoreHistogramTest, OtherPageLoaded) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
core()->OnStop();
histogram_tester_.ExpectTotalCount(kCountAtSuccess, 0);
@@ -2384,9 +2382,9 @@ TEST_F(NetErrorHelperCoreHistogramTest, OtherPageLoadedAfterTimerFires) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
timer()->Fire();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME,
- kTestUrl);
+ kTestUrl);
core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
histogram_tester_.ExpectTotalCount(kCountAtSuccess, 0);
@@ -2415,7 +2413,7 @@ TEST_F(NetErrorHelperCoreHistogramTest, SamePageLoadedAfterLoadStarts) {
timer()->Fire();
// Autoreload attempt starts
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
// User does a manual reload
DoSuccessLoad();
@@ -2432,9 +2430,9 @@ TEST_F(NetErrorHelperCoreHistogramTest, ErrorPageLoadedAfterTimerFires) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
timer()->Fire();
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
EXPECT_TRUE(core()->ShouldSuppressErrorPage(NetErrorHelperCore::MAIN_FRAME,
- default_url()));
+ default_url()));
DoErrorLoad(net::ERR_CONNECTION_RESET);
histogram_tester_.ExpectTotalCount(kCountAtSuccess, 0);
@@ -2447,9 +2445,9 @@ TEST_F(NetErrorHelperCoreHistogramTest, ErrorPageLoadedAfterTimerFires) {
TEST_F(NetErrorHelperCoreHistogramTest, SuccessPageLoadedBeforeTimerFires) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
- NetErrorHelperCore::NON_ERROR_PAGE);
+ NetErrorHelperCore::NON_ERROR_PAGE);
core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME,
- GURL(kFailedHttpsUrl));
+ GURL(kFailedHttpsUrl));
histogram_tester_.ExpectTotalCount(kCountAtSuccess, 0);
histogram_tester_.ExpectTotalCount(kErrorAtSuccess, 0);
@@ -2458,21 +2456,36 @@ TEST_F(NetErrorHelperCoreHistogramTest, SuccessPageLoadedBeforeTimerFires) {
histogram_tester_.ExpectTotalCount(kErrorAtStop, 1);
}
-
TEST_F(NetErrorHelperCoreTest, ExplicitReloadSucceeds) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
EXPECT_EQ(0, reload_count());
- core()->ExecuteButtonPress(true, NetErrorHelperCore::RELOAD_BUTTON);
+ core()->ExecuteButtonPress(NetErrorHelperCore::RELOAD_BUTTON);
EXPECT_EQ(1, reload_count());
}
TEST_F(NetErrorHelperCoreTest, ExplicitShowSavedSucceeds) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
EXPECT_EQ(0, show_saved_count());
- core()->ExecuteButtonPress(true, NetErrorHelperCore::SHOW_SAVED_COPY_BUTTON);
+ core()->ExecuteButtonPress(NetErrorHelperCore::SHOW_SAVED_COPY_BUTTON);
EXPECT_EQ(1, show_saved_count());
EXPECT_EQ(GURL(kFailedUrl), show_saved_url());
}
+TEST_F(NetErrorHelperCoreTest, CanNotShowNetworkDiagnostics) {
+ core()->OnSetCanShowNetworkDiagnosticsDialog(false);
+ DoErrorLoad(net::ERR_CONNECTION_RESET);
+ EXPECT_FALSE(last_can_show_network_diagnostics_dialog());
+}
+
+TEST_F(NetErrorHelperCoreTest, CanShowNetworkDiagnostics) {
+ core()->OnSetCanShowNetworkDiagnosticsDialog(true);
+ DoErrorLoad(net::ERR_CONNECTION_RESET);
+ EXPECT_TRUE(last_can_show_network_diagnostics_dialog());
+
+ core()->ExecuteButtonPress(NetErrorHelperCore::DIAGNOSE_ERROR);
+ EXPECT_EQ(1, diagnose_error_count());
+ EXPECT_EQ(GURL(kFailedUrl), diagnose_error_url());
+}
+
} // namespace
} // namespace error_page
diff --git a/chromium/components/favicon.gypi b/chromium/components/favicon.gypi
index f7666ec9764..a75c937c96b 100644
--- a/chromium/components/favicon.gypi
+++ b/chromium/components/favicon.gypi
@@ -10,7 +10,6 @@
'type': 'static_library',
'dependencies': [
'../base/base.gyp:base',
- '../content/content.gyp:content_browser',
'../skia/skia.gyp:skia',
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx',
@@ -37,6 +36,8 @@
'favicon/core/favicon_service.h',
'favicon/core/favicon_url.cc',
'favicon/core/favicon_url.h',
+ 'favicon/core/favicon_util.cc',
+ 'favicon/core/favicon_util.h',
'favicon/core/large_icon_service.cc',
'favicon/core/large_icon_service.h',
],
@@ -70,6 +71,11 @@
'include_dirs': [
'..',
],
+ 'sources!': [
+ 'favicon/core/fallback_icon_client.h',
+ 'favicon/core/fallback_icon_service.cc',
+ 'favicon/core/fallback_icon_service.h',
+ ],
},
],
}],
diff --git a/chromium/components/flags_ui.gypi b/chromium/components/flags_ui.gypi
new file mode 100644
index 00000000000..a6ab42c9314
--- /dev/null
+++ b/chromium/components/flags_ui.gypi
@@ -0,0 +1,26 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/flags_ui
+ 'target_name': 'flags_ui',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'flags_ui/flags_ui_constants.cc',
+ 'flags_ui/flags_ui_constants.h',
+ 'flags_ui/flags_ui_pref_names.cc',
+ 'flags_ui/flags_ui_pref_names.h',
+ 'flags_ui/flags_storage.h',
+ 'flags_ui/pref_service_flags_storage.cc',
+ 'flags_ui/pref_service_flags_storage.h',
+ ],
+ },
+ ],
+}
diff --git a/chromium/components/flags_ui_strings.grdp b/chromium/components/flags_ui_strings.grdp
new file mode 100644
index 00000000000..71b4dd71f3c
--- /dev/null
+++ b/chromium/components/flags_ui_strings.grdp
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <message name="IDS_FLAGS_UI_LONG_TITLE" desc="Long version of the title for the about:flags page.">
+ Careful, these experiments may bite
+ </message>
+ <message name="IDS_FLAGS_UI_TABLE_TITLE" desc="Title for the experiments table on the about:flags page.">
+ Experiments
+ </message>
+ <message name="IDS_FLAGS_UI_WARNING_HEADER" desc="Text right before the warning body text.">
+ WARNING
+ </message>
+ <message name="IDS_FLAGS_UI_WARNING_TEXT" desc="Text at the top of the about:flags page, warning users that the about:flags contents are volatile.">
+ These experimental features may change, break, or disappear at any time. We make absolutely no guarantees about what may happen if you turn one of these experiments on, and your browser may even spontaneously combust. Jokes aside, your browser may delete all your data, or your security and privacy could be compromised in unexpected ways. Any experiments you enable will be enabled for all users of this browser. Please proceed with caution.
+ </message>
+ <message name="IDS_FLAGS_UI_PROMOTE_BETA_CHANNEL" desc="Shown on the about:flags page when we want to promote the Chrome beta channel">
+ Interested in cool new Chrome features? Try our beta channel at chrome.com/beta.
+ </message>
+ <message name="IDS_FLAGS_UI_PROMOTE_DEV_CHANNEL" desc="Shown on the about:flags page when we want to promote the Chrome developer channel">
+ Interested in cool new Chrome features? Try our dev channel at chrome.com/dev.
+ </message>
+ <message name="IDS_FLAGS_UI_DISABLE" desc="The link for disabling a labs experiment.">
+ Disable
+ </message>
+ <message name="IDS_FLAGS_UI_ENABLE" desc="The link for enabling a labs experiment.">
+ Enable
+ </message>
+ <message name="IDS_FLAGS_UI_RESET_ALL_BUTTON" desc="Text on a button that resets all experiments to their default state when clicked.">
+ Reset all to default
+ </message>
+ <message name="IDS_FLAGS_UI_NO_EXPERIMENTS_AVAILABLE" desc="Shown if no experiments are available">
+ Aww, it looks like there are currently no experiments available.
+ </message>
+ <message name="IDS_FLAGS_UI_UNSUPPORTED_TABLE_TITLE" desc="Title for the unsupported experiments table on the about:flags page. It lists all experiments that are not available on the current platform.">
+ Unavailable Experiments
+ </message>
+ <message name="IDS_FLAGS_UI_NO_UNSUPPORTED_EXPERIMENTS" desc="Show if there are no unavailable experiments.">
+ All experiments are available on your platform!
+ </message>
+ <message name="IDS_FLAGS_UI_NOT_AVAILABLE" desc="Shown instead of the Enable/Disable link, to let the user know that an experiment is not available on the current platform.">
+ Sorry, this experiment is not available on your platform.
+ </message>
+ <message name="IDS_FLAGS_UI_ENABLE_NACL_NAME" desc="Name of the 'Enable Native Client' lab.">
+ Native Client
+ </message>
+ <if expr="not chromeos">
+ <message name="IDS_FLAGS_UI_RELAUNCH_BUTTON" desc="Text on a button that relaunches Chrome when clicked. ">
+ Relaunch Now
+ </message>
+ </if>
+ <if expr="chromeos">
+ <message name="IDS_FLAGS_UI_RELAUNCH_BUTTON" desc="Text on a button that restarts Chrome OS when clicked. ">
+ Restart Now
+ </message>
+ <message name="IDS_FLAGS_UI_SYSTEM_OWNER_ONLY" desc="A warning that flags that apply system-wide can only be set by the owner.">
+ Flags that apply system-wide can only be set by the owner: <ph name="OWNER_EMAIL">$1<ex>owner@example.com</ex></ph>.
+ </message>
+ </if>
+</grit-part>
diff --git a/chromium/components/gcm_driver.gypi b/chromium/components/gcm_driver.gypi
index a52086c1fec..de43bb5768d 100644
--- a/chromium/components/gcm_driver.gypi
+++ b/chromium/components/gcm_driver.gypi
@@ -5,15 +5,36 @@
{
'targets': [
{
+ # GN version: //components/gcm_driver/common
+ 'target_name': 'gcm_driver_common',
+ 'type': '<(component)',
+ 'include_dirs': [
+ '..',
+ ],
+ 'defines': [
+ 'GCM_DRIVER_IMPLEMENTATION',
+ ],
+ 'sources': [
+ # Note: file list duplicated in GN build.
+ 'gcm_driver/common/gcm_driver_export.h',
+ 'gcm_driver/common/gcm_messages.cc',
+ 'gcm_driver/common/gcm_messages.h',
+ ],
+ },
+ {
# GN version: //components/gcm_driver
'target_name': 'gcm_driver',
'type': 'static_library',
'dependencies': [
+ 'gcm_driver_common',
+ 'gcm_driver_crypto',
'os_crypt',
+ 'sync_driver',
'../base/base.gyp:base',
'../google_apis/gcm/gcm.gyp:gcm',
'../net/net.gyp:net',
'../sync/sync.gyp:sync_proto',
+ '../url/url.gyp:url_lib',
],
'include_dirs': [
'..',
@@ -26,6 +47,8 @@
'gcm_driver/default_gcm_app_handler.h',
'gcm_driver/gcm_account_mapper.cc',
'gcm_driver/gcm_account_mapper.h',
+ 'gcm_driver/gcm_account_tracker.cc',
+ 'gcm_driver/gcm_account_tracker.h',
'gcm_driver/gcm_activity.cc',
'gcm_driver/gcm_activity.h',
'gcm_driver/gcm_app_handler.cc',
@@ -46,12 +69,16 @@
'gcm_driver/gcm_connection_observer.h',
'gcm_driver/gcm_delayed_task_controller.cc',
'gcm_driver/gcm_delayed_task_controller.h',
+ 'gcm_driver/gcm_desktop_utils.cc',
+ 'gcm_driver/gcm_desktop_utils.h',
'gcm_driver/gcm_driver.cc',
'gcm_driver/gcm_driver.h',
'gcm_driver/gcm_driver_android.cc',
'gcm_driver/gcm_driver_android.h',
'gcm_driver/gcm_driver_desktop.cc',
'gcm_driver/gcm_driver_desktop.h',
+ 'gcm_driver/gcm_internals_constants.cc',
+ 'gcm_driver/gcm_internals_constants.h',
'gcm_driver/gcm_stats_recorder_impl.cc',
'gcm_driver/gcm_stats_recorder_impl.h',
'gcm_driver/registration_info.cc',
@@ -59,11 +86,6 @@
'gcm_driver/system_encryptor.cc',
'gcm_driver/system_encryptor.h',
],
- 'variables': {
- 'proto_in_dir': 'gcm_driver/proto',
- 'proto_out_dir': 'components/gcm_driver/proto',
- },
- 'includes': [ '../build/protoc.gypi' ],
'conditions': [
['OS == "android"', {
'dependencies': [
@@ -83,13 +105,12 @@
'gcm_driver/gcm_client_factory.h',
'gcm_driver/gcm_client_impl.cc',
'gcm_driver/gcm_client_impl.h',
- 'gcm_driver/gcm_delayed_task_controller.cc',
- 'gcm_driver/gcm_delayed_task_controller.h',
+ 'gcm_driver/gcm_desktop_utils.cc',
+ 'gcm_driver/gcm_desktop_utils.h',
'gcm_driver/gcm_driver_desktop.cc',
'gcm_driver/gcm_driver_desktop.h',
'gcm_driver/gcm_stats_recorder_impl.cc',
'gcm_driver/gcm_stats_recorder_impl.h',
- 'gcm_driver/proto/gcm_channel_status.proto',
],
}],
['chromeos == 1', {
@@ -182,6 +203,61 @@
'gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h',
],
},
+ {
+ # GN version: //components/gcm_driver/crypto
+ 'target_name': 'gcm_driver_crypto',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'gcm_driver_crypto_proto',
+ '../base/base.gyp:base',
+ '../components/components.gyp:leveldb_proto',
+ '../crypto/crypto.gyp:crypto',
+ '../net/net.gyp:net',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: file list duplicated in GN build.
+ 'gcm_driver/crypto/encryption_header_parsers.cc',
+ 'gcm_driver/crypto/encryption_header_parsers.h',
+ 'gcm_driver/crypto/gcm_encryption_provider.cc',
+ 'gcm_driver/crypto/gcm_encryption_provider.h',
+ 'gcm_driver/crypto/gcm_key_store.cc',
+ 'gcm_driver/crypto/gcm_key_store.h',
+ 'gcm_driver/crypto/gcm_message_cryptographer.cc',
+ 'gcm_driver/crypto/gcm_message_cryptographer.h',
+ 'gcm_driver/crypto/gcm_message_cryptographer_nss.cc',
+ 'gcm_driver/crypto/gcm_message_cryptographer_openssl.cc',
+ ],
+ 'conditions': [
+ ['use_openssl==1', {
+ 'sources!': [
+ 'gcm_driver/crypto/gcm_message_cryptographer_nss.cc',
+ ],
+ 'dependencies': [
+ '../third_party/boringssl/boringssl.gyp:boringssl',
+ ],
+ }, {
+ 'sources!': [
+ 'gcm_driver/crypto/gcm_message_cryptographer_openssl.cc',
+ ],
+ }],
+ ],
+ },
+ {
+ # GN version: //components/gcm_driver/crypto/proto
+ 'target_name': 'gcm_driver_crypto_proto',
+ 'type': 'static_library',
+ 'sources': [
+ 'gcm_driver/crypto/proto/gcm_encryption_data.proto',
+ ],
+ 'variables': {
+ 'proto_in_dir': 'gcm_driver/crypto/proto',
+ 'proto_out_dir': 'components/gcm_driver/crypto/proto',
+ },
+ 'includes': [ '../build/protoc.gypi' ],
+ },
],
'conditions': [
['OS == "android"', {
diff --git a/chromium/components/google.gypi b/chromium/components/google.gypi
index 9ab6bac8287..5bc0a7429a5 100644
--- a/chromium/components/google.gypi
+++ b/chromium/components/google.gypi
@@ -13,9 +13,10 @@
'../net/net.gyp:net',
'../url/url.gyp:url_lib',
'components_strings.gyp:components_strings',
+ 'data_use_measurement_core',
'keyed_service_core',
'pref_registry',
- 'url_fixer',
+ 'url_formatter/url_formatter.gyp:url_formatter',
],
'include_dirs': [
'..',
@@ -24,8 +25,6 @@
# Note: sources duplicated in GN build.
'google/core/browser/google_pref_names.cc',
'google/core/browser/google_pref_names.h',
- 'google/core/browser/google_search_metrics.cc',
- 'google/core/browser/google_search_metrics.h',
'google/core/browser/google_switches.cc',
'google/core/browser/google_switches.h',
'google/core/browser/google_url_tracker.cc',
diff --git a/chromium/components/history.gypi b/chromium/components/history.gypi
index e07b782fe7d..64adec8e256 100644
--- a/chromium/components/history.gypi
+++ b/chromium/components/history.gypi
@@ -29,6 +29,7 @@
'keyed_service_core',
'query_parser',
'signin_core_browser',
+ 'url_formatter/url_formatter.gyp:url_formatter',
],
'export_dependent_settings': [
'../skia/skia.gyp:skia',
diff --git a/chromium/components/html_viewer/html_viewer_resources.grd b/chromium/components/html_viewer/html_viewer_resources.grd
new file mode 100644
index 00000000000..60b8e271b88
--- /dev/null
+++ b/chromium/components/html_viewer/html_viewer_resources.grd
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0" current_release="1">
+ <outputs>
+ <output filename="grit/html_viewer_resources.h" type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="html_viewer_resources.pak" type="data_package"/>
+ </outputs>
+ <translations />
+</grit>
diff --git a/chromium/components/infobars.gypi b/chromium/components/infobars.gypi
index 449082c6c0d..8c2449c8ae0 100644
--- a/chromium/components/infobars.gypi
+++ b/chromium/components/infobars.gypi
@@ -38,6 +38,14 @@
'infobars/core/simple_alert_infobar_delegate.cc',
'infobars/core/simple_alert_infobar_delegate.h',
],
+ 'conditions': [
+ ['OS != "ios" and OS != "android"', {
+ 'dependencies': [
+ '../ui/gfx/gfx.gyp:gfx_vector_icons',
+ '../ui/native_theme/native_theme.gyp:native_theme',
+ ],
+ }],
+ ],
},
],
}
diff --git a/chromium/components/invalidation.gypi b/chromium/components/invalidation.gypi
index 81e255e4655..d9f0a693c0d 100644
--- a/chromium/components/invalidation.gypi
+++ b/chromium/components/invalidation.gypi
@@ -53,6 +53,8 @@
'../base/base.gyp:base_prefs',
'../google_apis/google_apis.gyp:google_apis',
'../jingle/jingle.gyp:notifier',
+ '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_proto_cpp',
+ 'data_use_measurement_core',
'gcm_driver',
'keyed_service_core',
'pref_registry',
@@ -151,6 +153,9 @@
'gcm_driver_test_support',
'keyed_service_core',
],
+ 'export_dependent_settings': [
+ '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_proto_cpp',
+ ],
'include_dirs': [
'..',
],
@@ -220,6 +225,7 @@
'dependencies': [
'invalidation_java',
'../base/base.gyp:base_java_test_support',
+ '../content/content_shell_and_tests.gyp:content_java_test_support',
],
'variables': {
'java_in_dir': 'invalidation/impl/android/javatests',
@@ -227,23 +233,6 @@
'includes': [ '../build/java.gypi' ],
},
{
- 'target_name': 'invalidation_junit_tests',
- 'type': 'none',
- 'dependencies': [
- 'invalidation_java',
- '../base/base.gyp:base_java',
- '../base/base.gyp:base_java_test_support',
- '../testing/android/junit/junit_test.gyp:junit_test_support',
- ],
- 'variables': {
- 'main_class': 'org.chromium.testing.local.JunitTestMain',
- 'src_paths': [
- 'invalidation/impl/android/junit/'
- ],
- },
- 'includes': [ '../build/host_jar.gypi' ],
- },
- {
'target_name': 'invalidation_jni_headers',
'type': 'none',
'sources': [
diff --git a/chromium/components/keyed_service/DEPS b/chromium/components/keyed_service/DEPS
new file mode 100644
index 00000000000..5c12ca8ad83
--- /dev/null
+++ b/chromium/components/keyed_service/DEPS
@@ -0,0 +1,8 @@
+include_rules = [
+ # KeyedService is a layered component; subdirectories must introduce
+ # allowances of //content dependencies as appropriate.
+ "-components/keyed_service/content",
+
+ "+components/pref_registry",
+ "+components/user_prefs",
+]
diff --git a/chromium/components/keyed_service/OWNERS b/chromium/components/keyed_service/OWNERS
new file mode 100644
index 00000000000..6e5450111c8
--- /dev/null
+++ b/chromium/components/keyed_service/OWNERS
@@ -0,0 +1,2 @@
+erg@chromium.org
+phajdan.jr@chromium.org
diff --git a/chromium/components/keyed_service/README b/chromium/components/keyed_service/README
new file mode 100644
index 00000000000..d12f06af64e
--- /dev/null
+++ b/chromium/components/keyed_service/README
@@ -0,0 +1,9 @@
+KeyedService is a layered component
+(https://sites.google.com/a/chromium.org/dev/developers/design-documents/layered-components-design)
+to enable it to be shared cleanly on iOS.
+
+This component has the following structure:
+
+- core/: shared code that does not depend on src/content/ or src/ios/
+- content/: Code based on the content layer.
+- ios/: Code based on src/ios.
diff --git a/chromium/components/keyed_service/content/BUILD.gn b/chromium/components/keyed_service/content/BUILD.gn
new file mode 100644
index 00000000000..78d87ff07f5
--- /dev/null
+++ b/chromium/components/keyed_service/content/BUILD.gn
@@ -0,0 +1,44 @@
+# 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.
+
+assert(!is_ios)
+
+component("content") {
+ output_name = "keyed_service_content"
+ sources = [
+ "browser_context_dependency_manager.cc",
+ "browser_context_dependency_manager.h",
+ "browser_context_keyed_base_factory.cc",
+ "browser_context_keyed_base_factory.h",
+ "browser_context_keyed_service_factory.cc",
+ "browser_context_keyed_service_factory.h",
+ "browser_context_keyed_service_shutdown_notifier_factory.cc",
+ "browser_context_keyed_service_shutdown_notifier_factory.h",
+ "refcounted_browser_context_keyed_service_factory.cc",
+ "refcounted_browser_context_keyed_service_factory.h",
+ ]
+
+ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+ configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+
+ defines = [ "KEYED_SERVICE_IMPLEMENTATION" ]
+
+ deps = [
+ "//base",
+ "//base/third_party/dynamic_annotations",
+ "//components/keyed_service/core",
+ "//content/public/common",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "browser_context_dependency_manager_unittest.cc",
+ ]
+ deps = [
+ ":content",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/keyed_service/content/DEPS b/chromium/components/keyed_service/content/DEPS
new file mode 100644
index 00000000000..c24130ef510
--- /dev/null
+++ b/chromium/components/keyed_service/content/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+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
new file mode 100644
index 00000000000..113f1d9ebe9
--- /dev/null
+++ b/chromium/components/keyed_service/content/browser_context_dependency_manager.cc
@@ -0,0 +1,100 @@
+// 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/keyed_service/content/browser_context_dependency_manager.h"
+
+#include "base/memory/singleton.h"
+#include "base/trace_event/trace_event.h"
+#include "content/public/browser/browser_context.h"
+
+#ifndef NDEBUG
+#include "base/command_line.h"
+#include "base/files/file_util.h"
+
+// Dumps dependency information about our browser context keyed services
+// into a dot file in the browser context directory.
+const char kDumpBrowserContextDependencyGraphFlag[] =
+ "dump-browser-context-graph";
+#endif // NDEBUG
+
+void BrowserContextDependencyManager::RegisterProfilePrefsForServices(
+ content::BrowserContext* context,
+ user_prefs::PrefRegistrySyncable* pref_registry) {
+ TRACE_EVENT0(
+ "browser",
+ "BrowserContextDependencyManager::RegisterProfilePrefsForServices");
+ RegisterPrefsForServices(context, pref_registry);
+}
+
+void BrowserContextDependencyManager::CreateBrowserContextServices(
+ content::BrowserContext* context) {
+ DoCreateBrowserContextServices(context, false);
+}
+
+void BrowserContextDependencyManager::CreateBrowserContextServicesForTest(
+ content::BrowserContext* context) {
+ DoCreateBrowserContextServices(context, true);
+}
+
+void BrowserContextDependencyManager::DoCreateBrowserContextServices(
+ content::BrowserContext* context,
+ bool is_testing_context) {
+ TRACE_EVENT0(
+ "browser",
+ "BrowserContextDependencyManager::DoCreateBrowserContextServices")
+ will_create_browser_context_services_callbacks_.Notify(context);
+ DependencyManager::CreateContextServices(context, is_testing_context);
+}
+
+void BrowserContextDependencyManager::DestroyBrowserContextServices(
+ content::BrowserContext* context) {
+ DependencyManager::DestroyContextServices(context);
+}
+
+scoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription>
+BrowserContextDependencyManager::
+RegisterWillCreateBrowserContextServicesCallbackForTesting(
+ const base::Callback<void(content::BrowserContext*)>& callback) {
+ return will_create_browser_context_services_callbacks_.Add(callback);
+}
+
+#ifndef NDEBUG
+void BrowserContextDependencyManager::AssertBrowserContextWasntDestroyed(
+ content::BrowserContext* context) {
+ DependencyManager::AssertContextWasntDestroyed(context);
+}
+
+void BrowserContextDependencyManager::MarkBrowserContextLiveForTesting(
+ content::BrowserContext* context) {
+ DependencyManager::MarkContextLiveForTesting(context);
+}
+#endif // NDEBUG
+
+// static
+BrowserContextDependencyManager*
+BrowserContextDependencyManager::GetInstance() {
+ return base::Singleton<BrowserContextDependencyManager>::get();
+}
+
+BrowserContextDependencyManager::BrowserContextDependencyManager() {
+}
+
+BrowserContextDependencyManager::~BrowserContextDependencyManager() {
+}
+
+#ifndef NDEBUG
+void BrowserContextDependencyManager::DumpContextDependencies(
+ base::SupportsUserData* 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(
+ kDumpBrowserContextDependencyGraphFlag)) {
+ base::FilePath dot_file =
+ static_cast<const content::BrowserContext*>(context)
+ ->GetPath()
+ .AppendASCII("browser-context-dependencies.dot");
+ DumpDependenciesAsGraphviz("BrowserContext", dot_file);
+ }
+}
+#endif // NDEBUG
diff --git a/chromium/components/keyed_service/content/browser_context_dependency_manager.h b/chromium/components/keyed_service/content/browser_context_dependency_manager.h
new file mode 100644
index 00000000000..42173b28a0a
--- /dev/null
+++ b/chromium/components/keyed_service/content/browser_context_dependency_manager.h
@@ -0,0 +1,106 @@
+// 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_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_DEPENDENCY_MANAGER_H_
+#define COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_DEPENDENCY_MANAGER_H_
+
+#include "base/callback_forward.h"
+#include "base/callback_list.h"
+#include "components/keyed_service/core/dependency_manager.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+class BrowserContextKeyedBaseFactory;
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+} // namespace base
+
+namespace content {
+class BrowserContext;
+}
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+// A singleton that listens for context destruction notifications and
+// rebroadcasts them to each BrowserContextKeyedBaseFactory in a safe order
+// based on the stated dependencies by each service.
+class KEYED_SERVICE_EXPORT BrowserContextDependencyManager
+ : public DependencyManager {
+ public:
+ // Registers profile-specific preferences for all services via |registry|.
+ // |context| should be the BrowserContext containing |registry| and is used as
+ // a key to prevent multiple registrations on the same BrowserContext in
+ // tests.
+ void RegisterProfilePrefsForServices(
+ content::BrowserContext* context,
+ user_prefs::PrefRegistrySyncable* registry);
+
+ // Called by each BrowserContext to alert us of its creation. Several
+ // services want to be started when a context is created. If you want your
+ // KeyedService to be started with the BrowserContext, override
+ // BrowserContextKeyedBaseFactory::ServiceIsCreatedWithBrowserContext() to
+ // return true. This method also registers any service-related preferences
+ // for non-incognito profiles.
+ void CreateBrowserContextServices(content::BrowserContext* context);
+
+ // Similar to CreateBrowserContextServices(), except this is used for creating
+ // test BrowserContexts - these contexts will not create services for any
+ // BrowserContextKeyedBaseFactories that return true from
+ // ServiceIsNULLWhileTesting().
+ void CreateBrowserContextServicesForTest(content::BrowserContext* context);
+
+ // Called by each BrowserContext to alert us that we should destroy services
+ // associated with it.
+ void DestroyBrowserContextServices(content::BrowserContext* context);
+
+ // Registers a |callback| that will be called just before executing
+ // CreateBrowserContextServices() or CreateBrowserContextServicesForTest().
+ // This can be useful in browser tests which wish to substitute test or mock
+ // builders for the keyed services.
+ scoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription>
+ RegisterWillCreateBrowserContextServicesCallbackForTesting(
+ const base::Callback<void(content::BrowserContext*)>& callback);
+
+#ifndef NDEBUG
+ // Debugging assertion called as part of GetServiceForBrowserContext in debug
+ // mode. This will NOTREACHED() whenever the user is trying to access a stale
+ // BrowserContext*.
+ void AssertBrowserContextWasntDestroyed(content::BrowserContext* context);
+
+ // Marks |context| as live (i.e., not stale). This method can be called as a
+ // safeguard against |AssertBrowserContextWasntDestroyed()| checks going off
+ // due to |context| aliasing a BrowserContext instance from a prior test
+ // (i.e., 0xWhatever might be created, be destroyed, and then a new
+ // BrowserContext object might be created at 0xWhatever).
+ void MarkBrowserContextLiveForTesting(content::BrowserContext* context);
+#endif // NDEBUG
+
+ static BrowserContextDependencyManager* GetInstance();
+
+ private:
+ friend class BrowserContextDependencyManagerUnittests;
+ friend struct base::DefaultSingletonTraits<BrowserContextDependencyManager>;
+
+ // Helper function used by CreateBrowserContextServices[ForTest].
+ void DoCreateBrowserContextServices(content::BrowserContext* context,
+ bool is_testing_context);
+
+ BrowserContextDependencyManager();
+ ~BrowserContextDependencyManager() override;
+
+#ifndef NDEBUG
+ // DependencyManager:
+ void DumpContextDependencies(base::SupportsUserData* context) const final;
+#endif // NDEBUG
+
+ // A list of callbacks to call just before executing
+ // CreateBrowserContextServices() or CreateBrowserContextServicesForTest().
+ base::CallbackList<void(content::BrowserContext*)>
+ will_create_browser_context_services_callbacks_;
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_DEPENDENCY_MANAGER_H_
diff --git a/chromium/components/keyed_service/content/browser_context_dependency_manager_unittest.cc b/chromium/components/keyed_service/content/browser_context_dependency_manager_unittest.cc
new file mode 100644
index 00000000000..fe8e0883ce3
--- /dev/null
+++ b/chromium/components/keyed_service/content/browser_context_dependency_manager_unittest.cc
@@ -0,0 +1,171 @@
+// 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/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class BrowserContextDependencyManagerUnittests : public ::testing::Test {
+ protected:
+ // To get around class access:
+ void DependOn(BrowserContextKeyedServiceFactory* child,
+ BrowserContextKeyedServiceFactory* parent) {
+ child->DependsOn(parent);
+ }
+
+ BrowserContextDependencyManager* manager() { return &dependency_manager_; }
+
+ std::vector<std::string>* shutdown_order() { return &shutdown_order_; }
+
+ private:
+ BrowserContextDependencyManager dependency_manager_;
+
+ std::vector<std::string> shutdown_order_;
+};
+
+class TestService : public BrowserContextKeyedServiceFactory {
+ public:
+ TestService(const std::string& name,
+ std::vector<std::string>* fill_on_shutdown,
+ BrowserContextDependencyManager* manager)
+ : BrowserContextKeyedServiceFactory("TestService", manager),
+ name_(name),
+ fill_on_shutdown_(fill_on_shutdown) {}
+
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override {
+ ADD_FAILURE() << "This isn't part of the tests!";
+ return NULL;
+ }
+
+ void BrowserContextShutdown(content::BrowserContext* context) override {
+ fill_on_shutdown_->push_back(name_);
+ }
+
+ private:
+ const std::string name_;
+ std::vector<std::string>* fill_on_shutdown_;
+};
+
+// Tests that we can deal with a single component.
+TEST_F(BrowserContextDependencyManagerUnittests, SingleCase) {
+ TestService service("service", shutdown_order(), manager());
+
+ manager()->DestroyBrowserContextServices(NULL);
+
+ ASSERT_EQ(1U, shutdown_order()->size());
+ EXPECT_STREQ("service", (*shutdown_order())[0].c_str());
+}
+
+// Tests that we get a simple one component depends on the other case.
+TEST_F(BrowserContextDependencyManagerUnittests, SimpleDependency) {
+ TestService parent("parent", shutdown_order(), manager());
+ TestService child("child", shutdown_order(), manager());
+ DependOn(&child, &parent);
+
+ manager()->DestroyBrowserContextServices(NULL);
+
+ ASSERT_EQ(2U, shutdown_order()->size());
+ EXPECT_STREQ("child", (*shutdown_order())[0].c_str());
+ EXPECT_STREQ("parent", (*shutdown_order())[1].c_str());
+}
+
+// Tests two children, one parent
+TEST_F(BrowserContextDependencyManagerUnittests, TwoChildrenOneParent) {
+ TestService parent("parent", shutdown_order(), manager());
+ TestService child1("child1", shutdown_order(), manager());
+ TestService child2("child2", shutdown_order(), manager());
+ DependOn(&child1, &parent);
+ DependOn(&child2, &parent);
+
+ manager()->DestroyBrowserContextServices(NULL);
+
+ ASSERT_EQ(3U, shutdown_order()->size());
+ EXPECT_STREQ("child2", (*shutdown_order())[0].c_str());
+ EXPECT_STREQ("child1", (*shutdown_order())[1].c_str());
+ EXPECT_STREQ("parent", (*shutdown_order())[2].c_str());
+}
+
+// Tests an M configuration
+TEST_F(BrowserContextDependencyManagerUnittests, MConfiguration) {
+ TestService parent1("parent1", shutdown_order(), manager());
+ TestService parent2("parent2", shutdown_order(), manager());
+
+ TestService child_of_1("child_of_1", shutdown_order(), manager());
+ DependOn(&child_of_1, &parent1);
+
+ TestService child_of_12("child_of_12", shutdown_order(), manager());
+ DependOn(&child_of_12, &parent1);
+ DependOn(&child_of_12, &parent2);
+
+ TestService child_of_2("child_of_2", shutdown_order(), manager());
+ DependOn(&child_of_2, &parent2);
+
+ manager()->DestroyBrowserContextServices(NULL);
+
+ ASSERT_EQ(5U, shutdown_order()->size());
+ EXPECT_STREQ("child_of_2", (*shutdown_order())[0].c_str());
+ EXPECT_STREQ("child_of_12", (*shutdown_order())[1].c_str());
+ EXPECT_STREQ("child_of_1", (*shutdown_order())[2].c_str());
+ EXPECT_STREQ("parent2", (*shutdown_order())[3].c_str());
+ EXPECT_STREQ("parent1", (*shutdown_order())[4].c_str());
+}
+
+// Tests that it can deal with a simple diamond.
+TEST_F(BrowserContextDependencyManagerUnittests, DiamondConfiguration) {
+ TestService parent("parent", shutdown_order(), manager());
+
+ TestService middle_row_1("middle_row_1", shutdown_order(), manager());
+ DependOn(&middle_row_1, &parent);
+
+ TestService middle_row_2("middle_row_2", shutdown_order(), manager());
+ DependOn(&middle_row_2, &parent);
+
+ TestService bottom("bottom", shutdown_order(), manager());
+ DependOn(&bottom, &middle_row_1);
+ DependOn(&bottom, &middle_row_2);
+
+ manager()->DestroyBrowserContextServices(NULL);
+
+ ASSERT_EQ(4U, shutdown_order()->size());
+ EXPECT_STREQ("bottom", (*shutdown_order())[0].c_str());
+ EXPECT_STREQ("middle_row_2", (*shutdown_order())[1].c_str());
+ EXPECT_STREQ("middle_row_1", (*shutdown_order())[2].c_str());
+ EXPECT_STREQ("parent", (*shutdown_order())[3].c_str());
+}
+
+// A final test that works with a more complex graph.
+TEST_F(BrowserContextDependencyManagerUnittests, ComplexGraph) {
+ TestService everything_depends_on_me(
+ "everything_depends_on_me", shutdown_order(), manager());
+
+ TestService intermediary_service(
+ "intermediary_service", shutdown_order(), manager());
+ DependOn(&intermediary_service, &everything_depends_on_me);
+
+ TestService specialized_service(
+ "specialized_service", shutdown_order(), manager());
+ DependOn(&specialized_service, &everything_depends_on_me);
+ DependOn(&specialized_service, &intermediary_service);
+
+ TestService other_root("other_root", shutdown_order(), manager());
+
+ TestService other_intermediary(
+ "other_intermediary", shutdown_order(), manager());
+ DependOn(&other_intermediary, &other_root);
+
+ TestService bottom("bottom", shutdown_order(), manager());
+ DependOn(&bottom, &specialized_service);
+ DependOn(&bottom, &other_intermediary);
+
+ manager()->DestroyBrowserContextServices(NULL);
+
+ ASSERT_EQ(6U, shutdown_order()->size());
+ EXPECT_STREQ("bottom", (*shutdown_order())[0].c_str());
+ EXPECT_STREQ("specialized_service", (*shutdown_order())[1].c_str());
+ EXPECT_STREQ("other_intermediary", (*shutdown_order())[2].c_str());
+ EXPECT_STREQ("intermediary_service", (*shutdown_order())[3].c_str());
+ EXPECT_STREQ("other_root", (*shutdown_order())[4].c_str());
+ EXPECT_STREQ("everything_depends_on_me", (*shutdown_order())[5].c_str());
+}
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
new file mode 100644
index 00000000000..fe461ffb8f0
--- /dev/null
+++ b/chromium/components/keyed_service/content/browser_context_keyed_base_factory.cc
@@ -0,0 +1,90 @@
+// 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/keyed_service/content/browser_context_keyed_base_factory.h"
+
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "content/public/browser/browser_context.h"
+
+BrowserContextKeyedBaseFactory::BrowserContextKeyedBaseFactory(
+ const char* name,
+ BrowserContextDependencyManager* manager)
+ : KeyedServiceBaseFactory(name, manager) {
+}
+
+BrowserContextKeyedBaseFactory::~BrowserContextKeyedBaseFactory() {
+}
+
+content::BrowserContext* BrowserContextKeyedBaseFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ DCHECK(CalledOnValidThread());
+
+#ifndef NDEBUG
+ AssertContextWasntDestroyed(context);
+#endif
+
+ // Safe default for the Incognito mode: no service.
+ if (context->IsOffTheRecord())
+ return NULL;
+
+ return context;
+}
+
+void BrowserContextKeyedBaseFactory::RegisterUserPrefsOnBrowserContextForTest(
+ content::BrowserContext* context) {
+ KeyedServiceBaseFactory::RegisterUserPrefsOnContextForTest(context);
+}
+
+bool BrowserContextKeyedBaseFactory::ServiceIsCreatedWithBrowserContext()
+ const {
+ return KeyedServiceBaseFactory::ServiceIsCreatedWithContext();
+}
+
+bool BrowserContextKeyedBaseFactory::ServiceIsNULLWhileTesting() const {
+ return KeyedServiceBaseFactory::ServiceIsNULLWhileTesting();
+}
+
+void BrowserContextKeyedBaseFactory::BrowserContextDestroyed(
+ content::BrowserContext* context) {
+ KeyedServiceBaseFactory::ContextDestroyed(context);
+}
+
+base::SupportsUserData* BrowserContextKeyedBaseFactory::GetContextToUse(
+ base::SupportsUserData* context) const {
+ return GetBrowserContextToUse(static_cast<content::BrowserContext*>(context));
+}
+
+bool BrowserContextKeyedBaseFactory::ServiceIsCreatedWithContext() const {
+ return ServiceIsCreatedWithBrowserContext();
+}
+
+void BrowserContextKeyedBaseFactory::ContextShutdown(
+ base::SupportsUserData* context) {
+ BrowserContextShutdown(static_cast<content::BrowserContext*>(context));
+}
+
+void BrowserContextKeyedBaseFactory::ContextDestroyed(
+ base::SupportsUserData* context) {
+ BrowserContextDestroyed(static_cast<content::BrowserContext*>(context));
+}
+
+void BrowserContextKeyedBaseFactory::RegisterPrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ RegisterProfilePrefs(registry);
+}
+
+void BrowserContextKeyedBaseFactory::SetEmptyTestingFactory(
+ base::SupportsUserData* context) {
+ SetEmptyTestingFactory(static_cast<content::BrowserContext*>(context));
+}
+
+bool BrowserContextKeyedBaseFactory::HasTestingFactory(
+ base::SupportsUserData* context) {
+ return HasTestingFactory(static_cast<content::BrowserContext*>(context));
+}
+
+void BrowserContextKeyedBaseFactory::CreateServiceNow(
+ base::SupportsUserData* 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
new file mode 100644
index 00000000000..fc5a5d36376
--- /dev/null
+++ b/chromium/components/keyed_service/content/browser_context_keyed_base_factory.h
@@ -0,0 +1,121 @@
+// 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_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_BASE_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_BASE_FACTORY_H_
+
+#include "components/keyed_service/core/keyed_service_base_factory.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+class BrowserContextDependencyManager;
+class PrefService;
+
+namespace content {
+class BrowserContext;
+}
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+// Base class for Factories that take a BrowserContext object and return some
+// service.
+//
+// Unless you're trying to make a new type of Factory, you probably don't want
+// this class, but its subclasses: BrowserContextKeyedServiceFactory and
+// RefcountedBrowserContextKeyedServiceFactory. This object describes general
+// dependency management between Factories; subclasses react to lifecycle
+// events and implement memory management.
+//
+// Note: this class is deprecated and should not be used and will be removed
+// once http://crbug.com/131843 and http://crbug.com/131844 are closed. If you
+// need to implement a new way to manage KeyedService lifetime, base your code
+// 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);
+ ~BrowserContextKeyedBaseFactory() override;
+
+ // Interface for people building a concrete FooServiceFactory: --------------
+
+ // Finds which browser context (if any) to use.
+ virtual content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const;
+
+ // By default, we create instances of a service lazily and wait until
+ // GetForBrowserContext() is called on our subclass. Some services need to be
+ // created as soon as the BrowserContext has been brought up.
+ virtual bool ServiceIsCreatedWithBrowserContext() const;
+
+ // By default, TestingBrowserContexts will be treated like normal contexts.
+ // You can override this so that by default, the service associated with the
+ // TestingBrowserContext is NULL. (This is just a shortcut around
+ // SetTestingFactory() to make sure our contexts don't directly refer to the
+ // services they use.)
+ bool ServiceIsNULLWhileTesting() const override;
+
+ // Interface for people building a type of BrowserContextKeyedFactory: -------
+
+ // 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.
+ //
+ // It is up to the individual factory types to determine what this two pass
+ // shutdown means. The general framework guarantees the following:
+ //
+ // - Each BrowserContextShutdown() is called in dependency order (and you may
+ // reach out to other services during this phase).
+ //
+ // - Each BrowserContextDestroyed() is called in dependency order. We will
+ // NOTREACHED() if you attempt to GetForBrowserContext() any other service.
+ // You should delete/deref/do other final memory management things during
+ // this phase. You must also call the base class method as the last thing
+ // you do.
+ virtual void BrowserContextShutdown(content::BrowserContext* context) = 0;
+ 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.
+ virtual void RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {}
+
+ // Because of ServiceIsNULLWhileTesting(), we need a way to tell different
+ // subclasses that they should disable testing.
+ virtual void SetEmptyTestingFactory(content::BrowserContext* context) = 0;
+
+ // Returns true if a testing factory function has been set for |context|.
+ virtual bool HasTestingFactory(content::BrowserContext* context) = 0;
+
+ // We also need a generalized, non-returning method that generates the object
+ // now for when we're creating the context.
+ virtual void CreateServiceNow(content::BrowserContext* context) = 0;
+
+ // KeyedServiceBaseFactory:
+ base::SupportsUserData* GetContextToUse(
+ base::SupportsUserData* context) const final;
+ bool ServiceIsCreatedWithContext() const final;
+ void ContextShutdown(base::SupportsUserData* context) final;
+ void ContextDestroyed(base::SupportsUserData* 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;
+};
+
+#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
new file mode 100644
index 00000000000..db69459aa81
--- /dev/null
+++ b/chromium/components/keyed_service/content/browser_context_keyed_service_factory.cc
@@ -0,0 +1,124 @@
+// 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/keyed_service/content/browser_context_keyed_service_factory.h"
+
+#include "base/logging.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(
+ content::BrowserContext* context,
+ TestingFactoryFunction testing_factory) {
+ KeyedServiceFactory::SetTestingFactory(
+ context,
+ reinterpret_cast<KeyedServiceFactory::TestingFactoryFunction>(
+ testing_factory));
+}
+
+KeyedService* BrowserContextKeyedServiceFactory::SetTestingFactoryAndUse(
+ content::BrowserContext* context,
+ TestingFactoryFunction testing_factory) {
+ return KeyedServiceFactory::SetTestingFactoryAndUse(
+ context,
+ reinterpret_cast<KeyedServiceFactory::TestingFactoryFunction>(
+ testing_factory));
+}
+
+BrowserContextKeyedServiceFactory::BrowserContextKeyedServiceFactory(
+ const char* name,
+ BrowserContextDependencyManager* manager)
+ : KeyedServiceFactory(name, manager) {
+}
+
+BrowserContextKeyedServiceFactory::~BrowserContextKeyedServiceFactory() {
+}
+
+KeyedService* BrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
+ content::BrowserContext* context,
+ bool create) {
+ return KeyedServiceFactory::GetServiceForContext(context, create);
+}
+
+content::BrowserContext*
+BrowserContextKeyedServiceFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ DCHECK(CalledOnValidThread());
+
+#ifndef NDEBUG
+ AssertContextWasntDestroyed(context);
+#endif
+
+ // Safe default for Incognito mode: no service.
+ if (context->IsOffTheRecord())
+ return nullptr;
+
+ return context;
+}
+
+void
+BrowserContextKeyedServiceFactory::RegisterUserPrefsOnBrowserContextForTest(
+ content::BrowserContext* context) {
+ KeyedServiceBaseFactory::RegisterUserPrefsOnContextForTest(context);
+}
+
+bool BrowserContextKeyedServiceFactory::ServiceIsCreatedWithBrowserContext()
+ const {
+ return KeyedServiceBaseFactory::ServiceIsCreatedWithContext();
+}
+
+bool BrowserContextKeyedServiceFactory::ServiceIsNULLWhileTesting() const {
+ return KeyedServiceBaseFactory::ServiceIsNULLWhileTesting();
+}
+
+void BrowserContextKeyedServiceFactory::BrowserContextShutdown(
+ content::BrowserContext* context) {
+ KeyedServiceFactory::ContextShutdown(context);
+}
+
+void BrowserContextKeyedServiceFactory::BrowserContextDestroyed(
+ content::BrowserContext* context) {
+ KeyedServiceFactory::ContextDestroyed(context);
+}
+
+scoped_ptr<KeyedService>
+BrowserContextKeyedServiceFactory::BuildServiceInstanceFor(
+ base::SupportsUserData* context) const {
+ // TODO(isherman): The wrapped BuildServiceInstanceFor() should return a
+ // scoped_ptr as well.
+ return make_scoped_ptr(
+ BuildServiceInstanceFor(static_cast<content::BrowserContext*>(context)));
+}
+
+bool BrowserContextKeyedServiceFactory::IsOffTheRecord(
+ base::SupportsUserData* context) const {
+ return static_cast<content::BrowserContext*>(context)->IsOffTheRecord();
+}
+
+base::SupportsUserData* BrowserContextKeyedServiceFactory::GetContextToUse(
+ base::SupportsUserData* context) const {
+ return GetBrowserContextToUse(static_cast<content::BrowserContext*>(context));
+}
+
+bool BrowserContextKeyedServiceFactory::ServiceIsCreatedWithContext() const {
+ return ServiceIsCreatedWithBrowserContext();
+}
+
+void BrowserContextKeyedServiceFactory::ContextShutdown(
+ base::SupportsUserData* context) {
+ BrowserContextShutdown(static_cast<content::BrowserContext*>(context));
+}
+
+void BrowserContextKeyedServiceFactory::ContextDestroyed(
+ base::SupportsUserData* context) {
+ BrowserContextDestroyed(static_cast<content::BrowserContext*>(context));
+}
+
+void BrowserContextKeyedServiceFactory::RegisterPrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ RegisterProfilePrefs(registry);
+}
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
new file mode 100644
index 00000000000..5543bbdc179
--- /dev/null
+++ b/chromium/components/keyed_service/content/browser_context_keyed_service_factory.h
@@ -0,0 +1,148 @@
+// 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_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_SERVICE_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_SERVICE_FACTORY_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+#include "components/keyed_service/core/keyed_service_factory.h"
+
+class BrowserContextDependencyManager;
+class KeyedService;
+
+namespace content {
+class BrowserContext;
+}
+
+// Base class for Factories that take a BrowserContext 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 which services are depended on.
+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 function that supplies the instance of a KeyedService for a given
+ // BrowserContext. This is used primarily for testing, where we want to feed
+ // a specific mock into the BCKSF system.
+ typedef scoped_ptr<KeyedService>(*TestingFactoryFunction)(
+ content::BrowserContext* context);
+
+ // Associates |factory| with |context| so that |factory| is used to create
+ // the KeyedService when requested. |factory| can be NULL to signal that
+ // KeyedService should be NULL. Multiple calls to SetTestingFactory() are
+ // allowed; previous services will be shut down.
+ void SetTestingFactory(content::BrowserContext* context,
+ TestingFactoryFunction factory);
+
+ // Associates |factory| with |context| and immediately returns the created
+ // KeyedService. Since the factory will be used immediately, it may not be
+ // NULL.
+ KeyedService* SetTestingFactoryAndUse(content::BrowserContext* context,
+ TestingFactoryFunction factory);
+
+ protected:
+ // BrowserContextKeyedServiceFactories must communicate with a
+ // BrowserContextDependencyManager. For all non-test code, write your subclass
+ // constructors like this:
+ //
+ // MyServiceFactory::MyServiceFactory()
+ // : BrowserContextKeyedServiceFactory(
+ // "MyService",
+ // BrowserContextDependencyManager::GetInstance())
+ // {}
+ BrowserContextKeyedServiceFactory(const char* name,
+ BrowserContextDependencyManager* manager);
+ ~BrowserContextKeyedServiceFactory() override;
+
+ // Common implementation that maps |context| 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* GetServiceForBrowserContext(content::BrowserContext* context,
+ bool create);
+
+ // Interface for people building a concrete FooServiceFactory: --------------
+
+ // Finds which browser context (if any) to use.
+ virtual content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const;
+
+ // By default, we create instances of a service lazily and wait until
+ // GetForBrowserContext() is called on our subclass. Some services need to be
+ // created as soon as the BrowserContext has been brought up.
+ virtual bool ServiceIsCreatedWithBrowserContext() const;
+
+ // By default, TestingBrowserContexts will be treated like normal contexts.
+ // You can override this so that by default, the service associated with the
+ // TestingBrowserContext is NULL. (This is just a shortcut around
+ // SetTestingFactory() to make sure our contexts don't directly refer to the
+ // services they use.)
+ bool ServiceIsNULLWhileTesting() const override;
+
+ // Interface for people building a type of BrowserContextKeyedFactory: -------
+
+ // All subclasses of BrowserContextKeyedServiceFactory must return a
+ // KeyedService instead of just a BrowserContextKeyedBase.
+ virtual KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) 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, BrowserContextShutdown() 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, BrowserContextDestroyed() is called on every ServiceFactory
+ // and the default implementation removes it from |mapping_| and deletes
+ // the pointer.
+ virtual void BrowserContextShutdown(content::BrowserContext* context);
+ virtual void BrowserContextDestroyed(content::BrowserContext* context);
+
+ 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.
+ virtual void RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {}
+
+ // KeyedServiceFactory:
+ scoped_ptr<KeyedService> BuildServiceInstanceFor(
+ base::SupportsUserData* context) const final;
+ bool IsOffTheRecord(base::SupportsUserData* context) const final;
+
+ // KeyedServiceBaseFactory:
+ base::SupportsUserData* GetContextToUse(
+ base::SupportsUserData* context) const final;
+ bool ServiceIsCreatedWithContext() const final;
+ void ContextShutdown(base::SupportsUserData* context) final;
+ void ContextDestroyed(base::SupportsUserData* context) final;
+ void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserContextKeyedServiceFactory);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_SERVICE_FACTORY_H_
diff --git a/chromium/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.cc b/chromium/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.cc
new file mode 100644
index 00000000000..5a75b5afcf6
--- /dev/null
+++ b/chromium/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.cc
@@ -0,0 +1,37 @@
+// 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/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
+
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
+
+BrowserContextKeyedServiceShutdownNotifierFactory::
+ BrowserContextKeyedServiceShutdownNotifierFactory(const char* name)
+ : BrowserContextKeyedServiceFactory(
+ name,
+ BrowserContextDependencyManager::GetInstance()) {
+}
+BrowserContextKeyedServiceShutdownNotifierFactory::
+ ~BrowserContextKeyedServiceShutdownNotifierFactory() {
+}
+
+KeyedServiceShutdownNotifier*
+BrowserContextKeyedServiceShutdownNotifierFactory::Get(
+ content::BrowserContext* context) {
+ return static_cast<KeyedServiceShutdownNotifier*>(
+ GetServiceForBrowserContext(context, true));
+}
+
+KeyedService*
+BrowserContextKeyedServiceShutdownNotifierFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ return new KeyedServiceShutdownNotifier;
+}
+
+content::BrowserContext*
+BrowserContextKeyedServiceShutdownNotifierFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ return context;
+}
diff --git a/chromium/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h b/chromium/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h
new file mode 100644
index 00000000000..dee630283e3
--- /dev/null
+++ b/chromium/components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.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_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_SERVICE_SHUTDOWN_NOTIFIER_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_SERVICE_SHUTDOWN_NOTIFIER_FACTORY_H_
+
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+class KeyedServiceShutdownNotifier;
+
+// A base class for factories for KeyedServiceShutdownNotifier objects that are
+// keyed on a BrowserContext.
+// To use this class, create a singleton subclass and declare its dependencies
+// in the constructor.
+class KEYED_SERVICE_EXPORT BrowserContextKeyedServiceShutdownNotifierFactory
+ : public BrowserContextKeyedServiceFactory {
+ public:
+ KeyedServiceShutdownNotifier* Get(content::BrowserContext* context);
+
+ protected:
+ explicit BrowserContextKeyedServiceShutdownNotifierFactory(const char* name);
+ ~BrowserContextKeyedServiceShutdownNotifierFactory() override;
+
+ private:
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+ content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const override;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserContextKeyedServiceShutdownNotifierFactory);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_SERVICE_SHUTDOWN_NOTIFIER_FACTORY_H_
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
new file mode 100644
index 00000000000..03c99158b48
--- /dev/null
+++ b/chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.cc
@@ -0,0 +1,121 @@
+// 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/keyed_service/content/refcounted_browser_context_keyed_service_factory.h"
+
+#include "base/logging.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/keyed_service/core/refcounted_keyed_service.h"
+#include "content/public/browser/browser_context.h"
+
+void RefcountedBrowserContextKeyedServiceFactory::SetTestingFactory(
+ content::BrowserContext* context,
+ TestingFactoryFunction testing_factory) {
+ RefcountedKeyedServiceFactory::SetTestingFactory(
+ context,
+ reinterpret_cast<RefcountedKeyedServiceFactory::TestingFactoryFunction>(
+ testing_factory));
+}
+
+scoped_refptr<RefcountedKeyedService>
+RefcountedBrowserContextKeyedServiceFactory::SetTestingFactoryAndUse(
+ content::BrowserContext* context,
+ TestingFactoryFunction testing_factory) {
+ return RefcountedKeyedServiceFactory::SetTestingFactoryAndUse(
+ context,
+ reinterpret_cast<RefcountedKeyedServiceFactory::TestingFactoryFunction>(
+ testing_factory));
+}
+
+RefcountedBrowserContextKeyedServiceFactory::
+ RefcountedBrowserContextKeyedServiceFactory(
+ const char* name,
+ BrowserContextDependencyManager* manager)
+ : RefcountedKeyedServiceFactory(name, manager) {
+}
+
+RefcountedBrowserContextKeyedServiceFactory::
+ ~RefcountedBrowserContextKeyedServiceFactory() {
+}
+
+scoped_refptr<RefcountedKeyedService>
+RefcountedBrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
+ content::BrowserContext* context,
+ bool create) {
+ return RefcountedKeyedServiceFactory::GetServiceForContext(context, create);
+}
+
+content::BrowserContext*
+RefcountedBrowserContextKeyedServiceFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ DCHECK(CalledOnValidThread());
+
+#ifndef NDEBUG
+ AssertContextWasntDestroyed(context);
+#endif
+
+ // Safe default for Incognito mode: no service.
+ if (context->IsOffTheRecord())
+ return nullptr;
+
+ return context;
+}
+
+bool RefcountedBrowserContextKeyedServiceFactory::
+ ServiceIsCreatedWithBrowserContext() const {
+ return KeyedServiceBaseFactory::ServiceIsCreatedWithContext();
+}
+
+bool RefcountedBrowserContextKeyedServiceFactory::ServiceIsNULLWhileTesting()
+ const {
+ return KeyedServiceBaseFactory::ServiceIsNULLWhileTesting();
+}
+
+void RefcountedBrowserContextKeyedServiceFactory::BrowserContextShutdown(
+ content::BrowserContext* context) {
+ RefcountedKeyedServiceFactory::ContextShutdown(context);
+}
+
+void RefcountedBrowserContextKeyedServiceFactory::BrowserContextDestroyed(
+ content::BrowserContext* context) {
+ RefcountedKeyedServiceFactory::ContextDestroyed(context);
+}
+
+scoped_refptr<RefcountedKeyedService>
+RefcountedBrowserContextKeyedServiceFactory::BuildServiceInstanceFor(
+ base::SupportsUserData* context) const {
+ return BuildServiceInstanceFor(
+ static_cast<content::BrowserContext*>(context));
+}
+
+bool RefcountedBrowserContextKeyedServiceFactory::IsOffTheRecord(
+ base::SupportsUserData* context) const {
+ return static_cast<content::BrowserContext*>(context)->IsOffTheRecord();
+}
+
+base::SupportsUserData*
+RefcountedBrowserContextKeyedServiceFactory::GetContextToUse(
+ base::SupportsUserData* context) const {
+ return GetBrowserContextToUse(static_cast<content::BrowserContext*>(context));
+}
+
+bool RefcountedBrowserContextKeyedServiceFactory::ServiceIsCreatedWithContext()
+ const {
+ return ServiceIsCreatedWithBrowserContext();
+}
+
+void RefcountedBrowserContextKeyedServiceFactory::ContextShutdown(
+ base::SupportsUserData* context) {
+ BrowserContextShutdown(static_cast<content::BrowserContext*>(context));
+}
+
+void RefcountedBrowserContextKeyedServiceFactory::ContextDestroyed(
+ base::SupportsUserData* context) {
+ BrowserContextDestroyed(static_cast<content::BrowserContext*>(context));
+}
+
+void RefcountedBrowserContextKeyedServiceFactory::RegisterPrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ RegisterProfilePrefs(registry);
+}
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
new file mode 100644
index 00000000000..f8350fdb539
--- /dev/null
+++ b/chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h
@@ -0,0 +1,144 @@
+// 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_KEYED_SERVICE_CONTENT_REFCOUNTED_BROWSER_CONTEXT_KEYED_SERVICE_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_CONTENT_REFCOUNTED_BROWSER_CONTEXT_KEYED_SERVICE_FACTORY_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+#include "components/keyed_service/core/refcounted_keyed_service_factory.h"
+
+class BrowserContextDependencyManager;
+class RefcountedKeyedService;
+
+namespace content {
+class BrowserContext;
+}
+
+// A specialized BrowserContextKeyedServiceFactory that manages a
+// RefcountedThreadSafe<>.
+//
+// While the factory returns RefcountedThreadSafe<>s, the factory itself is a
+// base::NotThreadSafe. Only call methods on this object on the UI thread.
+//
+// Implementers of RefcountedKeyedService should note that we guarantee that
+// ShutdownOnUIThread() is called on the UI thread, but actual object
+// destruction can happen anywhere.
+class KEYED_SERVICE_EXPORT RefcountedBrowserContextKeyedServiceFactory
+ : public RefcountedKeyedServiceFactory {
+ public:
+ // A function that supplies the instance of a KeyedService for a given
+ // BrowserContext. This is used primarily for testing, where we want to feed
+ // a specific mock into the BCKSF system.
+ typedef scoped_refptr<RefcountedKeyedService>(*TestingFactoryFunction)(
+ content::BrowserContext* context);
+
+ // Associates |factory| with |context| so that |factory| is used to create
+ // the KeyedService when requested. |factory| can be NULL to signal that
+ // KeyedService should be NULL. Multiple calls to SetTestingFactory() are
+ // allowed; previous services will be shut down.
+ void SetTestingFactory(content::BrowserContext* context,
+ TestingFactoryFunction factory);
+
+ // Associates |factory| with |context| and immediately returns the created
+ // KeyedService. Since the factory will be used immediately, it may not be
+ // NULL.
+ scoped_refptr<RefcountedKeyedService> SetTestingFactoryAndUse(
+ content::BrowserContext* context,
+ TestingFactoryFunction factory);
+
+ protected:
+ // RefcountedBrowserContextKeyedServiceFactories must communicate with a
+ // BrowserContextDependencyManager. For all non-test code, write your subclass
+ // constructors like this:
+ //
+ // MyServiceFactory::MyServiceFactory()
+ // : RefcountedBrowserContextKeyedServiceFactory(
+ // "MyService",
+ // BrowserContextDependencyManager::GetInstance())
+ // {}
+ RefcountedBrowserContextKeyedServiceFactory(
+ const char* name,
+ BrowserContextDependencyManager* manager);
+ ~RefcountedBrowserContextKeyedServiceFactory() override;
+
+ // Common implementation that maps |context| 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.
+ scoped_refptr<RefcountedKeyedService> GetServiceForBrowserContext(
+ content::BrowserContext* context,
+ bool create);
+
+ // Interface for people building a concrete FooServiceFactory: --------------
+
+ // Finds which browser context (if any) to use.
+ virtual content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const;
+
+ // By default, we create instances of a service lazily and wait until
+ // GetForBrowserContext() is called on our subclass. Some services need to be
+ // created as soon as the BrowserContext has been brought up.
+ virtual bool ServiceIsCreatedWithBrowserContext() const;
+
+ // By default, TestingBrowserContexts will be treated like normal contexts.
+ // You can override this so that by default, the service associated with the
+ // TestingBrowserContext is NULL. (This is just a shortcut around
+ // SetTestingFactory() to make sure our contexts don't directly refer to the
+ // services they use.)
+ bool ServiceIsNULLWhileTesting() const override;
+
+ // Interface for people building a type of BrowserContextKeyedFactory: -------
+
+ // All subclasses of BrowserContextKeyedServiceFactory must return a
+ // KeyedService instead of just a BrowserContextKeyedBase.
+ virtual scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
+ content::BrowserContext* context) 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, BrowserContextShutdown() 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, BrowserContextDestroyed() is called on every ServiceFactory
+ // and the default implementation removes it from |mapping_| and deletes
+ // the pointer.
+ virtual void BrowserContextShutdown(content::BrowserContext* context);
+ virtual void BrowserContextDestroyed(content::BrowserContext* context);
+
+ 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.
+ virtual void RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {}
+
+ // RefcountedKeyedServiceFactory:
+ scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
+ base::SupportsUserData* context) const final;
+ bool IsOffTheRecord(base::SupportsUserData* context) const final;
+
+ // KeyedServiceBaseFactory:
+ base::SupportsUserData* GetContextToUse(
+ base::SupportsUserData* context) const final;
+ bool ServiceIsCreatedWithContext() const final;
+ void ContextShutdown(base::SupportsUserData* context) final;
+ void ContextDestroyed(base::SupportsUserData* context) final;
+ void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
+
+ DISALLOW_COPY_AND_ASSIGN(RefcountedBrowserContextKeyedServiceFactory);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CONTENT_REFCOUNTED_BROWSER_CONTEXT_KEYED_SERVICE_FACTORY_H_
diff --git a/chromium/components/keyed_service/core/BUILD.gn b/chromium/components/keyed_service/core/BUILD.gn
new file mode 100644
index 00000000000..a89949f678a
--- /dev/null
+++ b/chromium/components/keyed_service/core/BUILD.gn
@@ -0,0 +1,48 @@
+# 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.
+
+component("core") {
+ output_name = "keyed_service_core"
+ sources = [
+ "dependency_graph.cc",
+ "dependency_graph.h",
+ "dependency_manager.cc",
+ "dependency_manager.h",
+ "dependency_node.h",
+ "keyed_service.cc",
+ "keyed_service.h",
+ "keyed_service_base_factory.cc",
+ "keyed_service_base_factory.h",
+ "keyed_service_export.h",
+ "keyed_service_factory.cc",
+ "keyed_service_factory.h",
+ "keyed_service_shutdown_notifier.cc",
+ "keyed_service_shutdown_notifier.h",
+ "refcounted_keyed_service.cc",
+ "refcounted_keyed_service.h",
+ "refcounted_keyed_service_factory.cc",
+ "refcounted_keyed_service_factory.h",
+ ]
+
+ configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+
+ defines = [ "KEYED_SERVICE_IMPLEMENTATION" ]
+
+ deps = [
+ "//base",
+ "//base:prefs",
+ "//components/user_prefs",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "dependency_graph_unittest.cc",
+ ]
+ deps = [
+ ":core",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/keyed_service/core/dependency_graph.cc b/chromium/components/keyed_service/core/dependency_graph.cc
new file mode 100644
index 00000000000..2b7f4126f9b
--- /dev/null
+++ b/chromium/components/keyed_service/core/dependency_graph.cc
@@ -0,0 +1,159 @@
+// 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/keyed_service/core/dependency_graph.h"
+
+#include <algorithm>
+#include <deque>
+#include <iterator>
+
+DependencyGraph::DependencyGraph() {}
+
+DependencyGraph::~DependencyGraph() {}
+
+void DependencyGraph::AddNode(DependencyNode* node) {
+ all_nodes_.push_back(node);
+ construction_order_.clear();
+}
+
+void DependencyGraph::RemoveNode(DependencyNode* node) {
+ all_nodes_.erase(std::remove(all_nodes_.begin(), all_nodes_.end(), node),
+ all_nodes_.end());
+
+ // Remove all dependency edges that contain this node.
+ EdgeMap::iterator it = edges_.begin();
+ while (it != edges_.end()) {
+ EdgeMap::iterator temp = it;
+ ++it;
+
+ if (temp->first == node || temp->second == node)
+ edges_.erase(temp);
+ }
+
+ construction_order_.clear();
+}
+
+void DependencyGraph::AddEdge(DependencyNode* depended,
+ DependencyNode* dependee) {
+ edges_.insert(std::make_pair(depended, dependee));
+ construction_order_.clear();
+}
+
+bool DependencyGraph::GetConstructionOrder(
+ std::vector<DependencyNode*>* order) {
+ if (construction_order_.empty() && !BuildConstructionOrder())
+ return false;
+
+ *order = construction_order_;
+ return true;
+}
+
+bool DependencyGraph::GetDestructionOrder(std::vector<DependencyNode*>* order) {
+ if (construction_order_.empty() && !BuildConstructionOrder())
+ return false;
+
+ *order = construction_order_;
+
+ // Destroy nodes in reverse order.
+ std::reverse(order->begin(), order->end());
+
+ return true;
+}
+
+bool DependencyGraph::BuildConstructionOrder() {
+ // Step 1: Build a set of nodes with no incoming edges.
+ std::deque<DependencyNode*> queue;
+ std::copy(all_nodes_.begin(), all_nodes_.end(), std::back_inserter(queue));
+
+ std::deque<DependencyNode*>::iterator queue_end = queue.end();
+ for (EdgeMap::const_iterator it = edges_.begin(); it != edges_.end(); ++it) {
+ queue_end = std::remove(queue.begin(), queue_end, it->second);
+ }
+ queue.erase(queue_end, queue.end());
+
+ // Step 2: Do the Kahn topological sort.
+ std::vector<DependencyNode*> output;
+ EdgeMap edges(edges_);
+ while (!queue.empty()) {
+ DependencyNode* node = queue.front();
+ queue.pop_front();
+ output.push_back(node);
+
+ std::pair<EdgeMap::iterator, EdgeMap::iterator> range =
+ edges.equal_range(node);
+ EdgeMap::iterator it = range.first;
+ while (it != range.second) {
+ DependencyNode* dest = it->second;
+ EdgeMap::iterator temp = it;
+ it++;
+ edges.erase(temp);
+
+ bool has_incoming_edges = false;
+ for (EdgeMap::iterator jt = edges.begin(); jt != edges.end(); ++jt) {
+ if (jt->second == dest) {
+ has_incoming_edges = true;
+ break;
+ }
+ }
+
+ if (!has_incoming_edges)
+ queue.push_back(dest);
+ }
+ }
+
+ if (!edges.empty()) {
+ // Dependency graph has a cycle.
+ return false;
+ }
+
+ construction_order_ = output;
+ return true;
+}
+
+std::string DependencyGraph::DumpAsGraphviz(
+ const std::string& toplevel_name,
+ const base::Callback<std::string(DependencyNode*)>& node_name_callback)
+ const {
+ std::string result("digraph {\n");
+
+ // Make a copy of all nodes.
+ std::deque<DependencyNode*> nodes;
+ std::copy(all_nodes_.begin(), all_nodes_.end(), std::back_inserter(nodes));
+
+ // State all dependencies and remove |second| so we don't generate an
+ // implicit dependency on the top level node.
+ std::deque<DependencyNode*>::iterator nodes_end(nodes.end());
+ result.append(" /* Dependencies */\n");
+ for (EdgeMap::const_iterator it = edges_.begin(); it != edges_.end(); ++it) {
+ result.append(" ");
+ result.append(node_name_callback.Run(it->second));
+ result.append(" -> ");
+ result.append(node_name_callback.Run(it->first));
+ result.append(";\n");
+
+ nodes_end = std::remove(nodes.begin(), nodes_end, it->second);
+ }
+ nodes.erase(nodes_end, nodes.end());
+
+ // Every node that doesn't depend on anything else will implicitly depend on
+ // the top level node.
+ result.append("\n /* Toplevel attachments */\n");
+ for (std::deque<DependencyNode*>::const_iterator it = nodes.begin();
+ it != nodes.end();
+ ++it) {
+ result.append(" ");
+ result.append(node_name_callback.Run(*it));
+ result.append(" -> ");
+ result.append(toplevel_name);
+ result.append(";\n");
+ }
+
+ result.append("\n /* Toplevel node */\n");
+ result.append(" ");
+ result.append(toplevel_name);
+ result.append(" [shape=box];\n");
+
+ result.append("}\n");
+ return result;
+}
diff --git a/chromium/components/keyed_service/core/dependency_graph.h b/chromium/components/keyed_service/core/dependency_graph.h
new file mode 100644
index 00000000000..98203b27249
--- /dev/null
+++ b/chromium/components/keyed_service/core/dependency_graph.h
@@ -0,0 +1,67 @@
+// 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_KEYED_SERVICE_CORE_DEPENDENCY_GRAPH_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_GRAPH_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+class DependencyNode;
+
+// Dynamic graph of dependencies between nodes.
+class KEYED_SERVICE_EXPORT DependencyGraph {
+ public:
+ DependencyGraph();
+ ~DependencyGraph();
+
+ // Adds/Removes a node from our list of live nodes. Removing will
+ // also remove live dependency links.
+ void AddNode(DependencyNode* node);
+ void RemoveNode(DependencyNode* node);
+
+ // Adds a dependency between two nodes.
+ void AddEdge(DependencyNode* depended, DependencyNode* dependee);
+
+ // Topologically sorts nodes to produce a safe construction order
+ // (all nodes after their dependees).
+ bool GetConstructionOrder(std::vector<DependencyNode*>* order)
+ WARN_UNUSED_RESULT;
+
+ // Topologically sorts nodes to produce a safe destruction order
+ // (all nodes before their dependees).
+ bool GetDestructionOrder(std::vector<DependencyNode*>* order)
+ WARN_UNUSED_RESULT;
+
+ // Returns representation of the dependency graph in graphviz format.
+ std::string DumpAsGraphviz(const std::string& toplevel_name,
+ const base::Callback<std::string(DependencyNode*)>&
+ node_name_callback) const;
+
+ private:
+ typedef std::multimap<DependencyNode*, DependencyNode*> EdgeMap;
+
+ // Populates |construction_order_| with computed construction order.
+ // Returns true on success.
+ bool BuildConstructionOrder() WARN_UNUSED_RESULT;
+
+ // Keeps track of all live nodes (see AddNode, RemoveNode).
+ std::vector<DependencyNode*> all_nodes_;
+
+ // Keeps track of edges of the dependency graph.
+ EdgeMap edges_;
+
+ // Cached construction order (needs rebuild with BuildConstructionOrder
+ // when empty).
+ std::vector<DependencyNode*> construction_order_;
+
+ DISALLOW_COPY_AND_ASSIGN(DependencyGraph);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_GRAPH_H_
diff --git a/chromium/components/keyed_service/core/dependency_graph_unittest.cc b/chromium/components/keyed_service/core/dependency_graph_unittest.cc
new file mode 100644
index 00000000000..3bf17583406
--- /dev/null
+++ b/chromium/components/keyed_service/core/dependency_graph_unittest.cc
@@ -0,0 +1,158 @@
+// 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/keyed_service/core/dependency_graph.h"
+#include "components/keyed_service/core/dependency_node.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class DependencyGraphTest : public testing::Test {};
+
+class DummyNode : public DependencyNode {
+ public:
+ explicit DummyNode(DependencyGraph* graph) : dependency_graph_(graph) {
+ dependency_graph_->AddNode(this);
+ }
+
+ ~DummyNode() { dependency_graph_->RemoveNode(this); }
+
+ private:
+ DependencyGraph* dependency_graph_;
+
+ DISALLOW_COPY_AND_ASSIGN(DummyNode);
+};
+
+// Tests that we can deal with a single component.
+TEST_F(DependencyGraphTest, SingleCase) {
+ DependencyGraph graph;
+ DummyNode node(&graph);
+
+ std::vector<DependencyNode*> construction_order;
+ EXPECT_TRUE(graph.GetConstructionOrder(&construction_order));
+ ASSERT_EQ(1U, construction_order.size());
+ EXPECT_EQ(&node, construction_order[0]);
+
+ std::vector<DependencyNode*> destruction_order;
+ EXPECT_TRUE(graph.GetDestructionOrder(&destruction_order));
+ ASSERT_EQ(1U, destruction_order.size());
+ EXPECT_EQ(&node, destruction_order[0]);
+}
+
+// Tests that we get a simple one component depends on the other case.
+TEST_F(DependencyGraphTest, SimpleDependency) {
+ DependencyGraph graph;
+ DummyNode parent(&graph);
+ DummyNode child(&graph);
+
+ graph.AddEdge(&parent, &child);
+
+ std::vector<DependencyNode*> construction_order;
+ EXPECT_TRUE(graph.GetConstructionOrder(&construction_order));
+ ASSERT_EQ(2U, construction_order.size());
+ EXPECT_EQ(&parent, construction_order[0]);
+ EXPECT_EQ(&child, construction_order[1]);
+
+ std::vector<DependencyNode*> destruction_order;
+ EXPECT_TRUE(graph.GetDestructionOrder(&destruction_order));
+ ASSERT_EQ(2U, destruction_order.size());
+ EXPECT_EQ(&child, destruction_order[0]);
+ EXPECT_EQ(&parent, destruction_order[1]);
+}
+
+// Tests two children, one parent.
+TEST_F(DependencyGraphTest, TwoChildrenOneParent) {
+ DependencyGraph graph;
+ DummyNode parent(&graph);
+ DummyNode child1(&graph);
+ DummyNode child2(&graph);
+
+ graph.AddEdge(&parent, &child1);
+ graph.AddEdge(&parent, &child2);
+
+ std::vector<DependencyNode*> construction_order;
+ EXPECT_TRUE(graph.GetConstructionOrder(&construction_order));
+ ASSERT_EQ(3U, construction_order.size());
+ EXPECT_EQ(&parent, construction_order[0]);
+ EXPECT_EQ(&child1, construction_order[1]);
+ EXPECT_EQ(&child2, construction_order[2]);
+
+ std::vector<DependencyNode*> destruction_order;
+ EXPECT_TRUE(graph.GetDestructionOrder(&destruction_order));
+ ASSERT_EQ(3U, destruction_order.size());
+ EXPECT_EQ(&child2, destruction_order[0]);
+ EXPECT_EQ(&child1, destruction_order[1]);
+ EXPECT_EQ(&parent, destruction_order[2]);
+}
+
+// Tests an M configuration.
+TEST_F(DependencyGraphTest, MConfiguration) {
+ DependencyGraph graph;
+
+ DummyNode parent1(&graph);
+ DummyNode parent2(&graph);
+
+ DummyNode child_of_1(&graph);
+ graph.AddEdge(&parent1, &child_of_1);
+
+ DummyNode child_of_12(&graph);
+ graph.AddEdge(&parent1, &child_of_12);
+ graph.AddEdge(&parent2, &child_of_12);
+
+ DummyNode child_of_2(&graph);
+ graph.AddEdge(&parent2, &child_of_2);
+
+ std::vector<DependencyNode*> construction_order;
+ EXPECT_TRUE(graph.GetConstructionOrder(&construction_order));
+ ASSERT_EQ(5U, construction_order.size());
+ EXPECT_EQ(&parent1, construction_order[0]);
+ EXPECT_EQ(&parent2, construction_order[1]);
+ EXPECT_EQ(&child_of_1, construction_order[2]);
+ EXPECT_EQ(&child_of_12, construction_order[3]);
+ EXPECT_EQ(&child_of_2, construction_order[4]);
+
+ std::vector<DependencyNode*> destruction_order;
+ EXPECT_TRUE(graph.GetDestructionOrder(&destruction_order));
+ ASSERT_EQ(5U, destruction_order.size());
+ EXPECT_EQ(&child_of_2, destruction_order[0]);
+ EXPECT_EQ(&child_of_12, destruction_order[1]);
+ EXPECT_EQ(&child_of_1, destruction_order[2]);
+ EXPECT_EQ(&parent2, destruction_order[3]);
+ EXPECT_EQ(&parent1, destruction_order[4]);
+}
+
+// Tests that it can deal with a simple diamond.
+TEST_F(DependencyGraphTest, DiamondConfiguration) {
+ DependencyGraph graph;
+
+ DummyNode parent(&graph);
+
+ DummyNode middle1(&graph);
+ graph.AddEdge(&parent, &middle1);
+
+ DummyNode middle2(&graph);
+ graph.AddEdge(&parent, &middle2);
+
+ DummyNode bottom(&graph);
+ graph.AddEdge(&middle1, &bottom);
+ graph.AddEdge(&middle2, &bottom);
+
+ std::vector<DependencyNode*> construction_order;
+ EXPECT_TRUE(graph.GetConstructionOrder(&construction_order));
+ ASSERT_EQ(4U, construction_order.size());
+ EXPECT_EQ(&parent, construction_order[0]);
+ EXPECT_EQ(&middle1, construction_order[1]);
+ EXPECT_EQ(&middle2, construction_order[2]);
+ EXPECT_EQ(&bottom, construction_order[3]);
+
+ std::vector<DependencyNode*> destruction_order;
+ EXPECT_TRUE(graph.GetDestructionOrder(&destruction_order));
+ ASSERT_EQ(4U, destruction_order.size());
+ EXPECT_EQ(&bottom, destruction_order[0]);
+ EXPECT_EQ(&middle2, destruction_order[1]);
+ EXPECT_EQ(&middle1, destruction_order[2]);
+ EXPECT_EQ(&parent, destruction_order[3]);
+}
+
+} // namespace
diff --git a/chromium/components/keyed_service/core/dependency_manager.cc b/chromium/components/keyed_service/core/dependency_manager.cc
new file mode 100644
index 00000000000..59cc867f6d2
--- /dev/null
+++ b/chromium/components/keyed_service/core/dependency_manager.cc
@@ -0,0 +1,143 @@
+// 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/keyed_service/core/dependency_manager.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/supports_user_data.h"
+#include "components/keyed_service/core/keyed_service_base_factory.h"
+
+#ifndef NDEBUG
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#endif // NDEBUG
+
+DependencyManager::DependencyManager() {
+}
+
+DependencyManager::~DependencyManager() {
+}
+
+void DependencyManager::AddComponent(KeyedServiceBaseFactory* component) {
+ dependency_graph_.AddNode(component);
+}
+
+void DependencyManager::RemoveComponent(KeyedServiceBaseFactory* component) {
+ dependency_graph_.RemoveNode(component);
+}
+
+void DependencyManager::AddEdge(KeyedServiceBaseFactory* depended,
+ KeyedServiceBaseFactory* dependee) {
+ dependency_graph_.AddEdge(depended, dependee);
+}
+
+void DependencyManager::RegisterPrefsForServices(
+ base::SupportsUserData* context,
+ user_prefs::PrefRegistrySyncable* pref_registry) {
+ std::vector<DependencyNode*> construction_order;
+ if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
+ NOTREACHED();
+ }
+
+ for (const auto& dependency_node : construction_order) {
+ KeyedServiceBaseFactory* factory =
+ static_cast<KeyedServiceBaseFactory*>(dependency_node);
+ base::SupportsUserData* typed_context = factory->GetTypedContext(context);
+ factory->RegisterPrefsIfNecessaryForContext(typed_context, pref_registry);
+ }
+}
+
+void DependencyManager::CreateContextServices(base::SupportsUserData* context,
+ bool is_testing_context) {
+#ifndef NDEBUG
+ MarkContextLiveForTesting(context);
+#endif
+
+ std::vector<DependencyNode*> construction_order;
+ if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
+ NOTREACHED();
+ }
+
+#ifndef NDEBUG
+ DumpContextDependencies(context);
+#endif
+
+ for (const auto& dependency_node : construction_order) {
+ KeyedServiceBaseFactory* factory =
+ static_cast<KeyedServiceBaseFactory*>(dependency_node);
+ base::SupportsUserData* typed_context = factory->GetTypedContext(context);
+ if (is_testing_context && factory->ServiceIsNULLWhileTesting() &&
+ !factory->HasTestingFactory(typed_context)) {
+ factory->SetEmptyTestingFactory(typed_context);
+ } else if (factory->ServiceIsCreatedWithContext()) {
+ factory->CreateServiceNow(typed_context);
+ }
+ }
+}
+
+void DependencyManager::DestroyContextServices(
+ base::SupportsUserData* context) {
+ std::vector<DependencyNode*> destruction_order;
+ if (!dependency_graph_.GetDestructionOrder(&destruction_order)) {
+ NOTREACHED();
+ }
+
+#ifndef NDEBUG
+ DumpContextDependencies(context);
+#endif
+
+ for (const auto& dependency_node : destruction_order) {
+ KeyedServiceBaseFactory* factory =
+ static_cast<KeyedServiceBaseFactory*>(dependency_node);
+ base::SupportsUserData* typed_context = factory->GetTypedContext(context);
+ factory->ContextShutdown(typed_context);
+ }
+
+#ifndef NDEBUG
+ // The context is now dead to the rest of the program.
+ dead_context_pointers_.insert(context);
+#endif
+
+ for (const auto& dependency_node : destruction_order) {
+ KeyedServiceBaseFactory* factory =
+ static_cast<KeyedServiceBaseFactory*>(dependency_node);
+ base::SupportsUserData* typed_context = factory->GetTypedContext(context);
+ factory->ContextDestroyed(typed_context);
+ }
+}
+
+#ifndef NDEBUG
+void DependencyManager::AssertContextWasntDestroyed(
+ base::SupportsUserData* context) {
+ if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) {
+ NOTREACHED() << "Attempted to access a context that was ShutDown(). "
+ << "This is most likely a heap smasher in progress. After "
+ << "KeyedService::Shutdown() completes, your service MUST "
+ << "NOT refer to depended services again.";
+ }
+}
+
+void DependencyManager::MarkContextLiveForTesting(
+ base::SupportsUserData* context) {
+ dead_context_pointers_.erase(context);
+}
+
+namespace {
+
+std::string KeyedServiceBaseFactoryGetNodeName(DependencyNode* node) {
+ return static_cast<KeyedServiceBaseFactory*>(node)->name();
+}
+
+} // namespace
+
+void DependencyManager::DumpDependenciesAsGraphviz(
+ const std::string& top_level_name,
+ const base::FilePath& dot_file) const {
+ DCHECK(!dot_file.empty());
+ std::string contents = dependency_graph_.DumpAsGraphviz(
+ top_level_name, base::Bind(&KeyedServiceBaseFactoryGetNodeName));
+ base::WriteFile(dot_file, contents.c_str(), contents.size());
+}
+#endif // NDEBUG
diff --git a/chromium/components/keyed_service/core/dependency_manager.h b/chromium/components/keyed_service/core/dependency_manager.h
new file mode 100644
index 00000000000..06e535737b5
--- /dev/null
+++ b/chromium/components/keyed_service/core/dependency_manager.h
@@ -0,0 +1,106 @@
+// 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_KEYED_SERVICE_CORE_DEPENDENCY_MANAGER_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_MANAGER_H_
+
+#include <string>
+
+#include "components/keyed_service/core/dependency_graph.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+#ifndef NDEBUG
+#include <set>
+#endif
+
+class KeyedServiceBaseFactory;
+
+namespace base {
+class FilePath;
+class SupportsUserData;
+}
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+// DependencyManager manages dependency between KeyedServiceBaseFactory
+// broadcasting the context creation and destruction to each factory in
+// a safe order based on the stated dependencies.
+class KEYED_SERVICE_EXPORT DependencyManager {
+ protected:
+ DependencyManager();
+ virtual ~DependencyManager();
+
+ // Adds/Removes a component from our list of live components. Removing will
+ // also remove live dependency links.
+ void AddComponent(KeyedServiceBaseFactory* component);
+ void RemoveComponent(KeyedServiceBaseFactory* component);
+
+ // Adds a dependency between two factories.
+ void AddEdge(KeyedServiceBaseFactory* depended,
+ KeyedServiceBaseFactory* dependee);
+
+ // 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,
+ user_prefs::PrefRegistrySyncable* registry);
+
+ // Called upon creation of |context| to create services that want to be
+ // started at the creation of a context and register service-related
+ // preferences.
+ //
+ // To have a KeyedService started when a context is created the method
+ // KeyedServiceBaseFactory::ServiceIsCreatedWithContext() must be overridden
+ // to return true.
+ //
+ // 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);
+
+ // Called upon destruction of |context| to destroy all services associated
+ // with it.
+ void DestroyContextServices(base::SupportsUserData* context);
+
+#ifndef NDEBUG
+ // Debugging assertion called as part of GetServiceForContext() in debug
+ // mode. This will NOTREACHED() whenever the |context| is considered stale.
+ void AssertContextWasntDestroyed(base::SupportsUserData* context);
+
+ // 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 am instance from a prior test (i.e., 0xWhatever might
+ // be created, be destroyed, and then a new object might be created at
+ // 0xWhatever).
+ void MarkContextLiveForTesting(base::SupportsUserData* context);
+
+ // Dumps service dependency graph as a Graphviz dot file |dot_file| with a
+ // title |top_level_name|. Helper for |DumpContextDependencies|.
+ void DumpDependenciesAsGraphviz(const std::string& top_level_name,
+ const base::FilePath& dot_file) const;
+#endif // NDEBUG
+
+ private:
+ friend class KeyedServiceBaseFactory;
+
+#ifndef NDEBUG
+ // Hook for subclass to dump the dependency graph of service for |context|.
+ virtual void DumpContextDependencies(
+ base::SupportsUserData* context) const = 0;
+#endif // NDEBUG
+
+ DependencyGraph dependency_graph_;
+
+#ifndef NDEBUG
+ // A list of context objects that have gone through the Shutdown() phase.
+ // 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_;
+#endif // NDEBUG
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_MANAGER_H_
diff --git a/chromium/components/keyed_service/core/dependency_node.h b/chromium/components/keyed_service/core/dependency_node.h
new file mode 100644
index 00000000000..3299a986679
--- /dev/null
+++ b/chromium/components/keyed_service/core/dependency_node.h
@@ -0,0 +1,16 @@
+// 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_KEYED_SERVICE_CORE_DEPENDENCY_NODE_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_NODE_H_
+
+// Base class representing a node in a DependencyGraph.
+class DependencyNode {
+ protected:
+ // This is intended to be used by the subclasses, not directly.
+ DependencyNode() {}
+ ~DependencyNode() {}
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_NODE_H_
diff --git a/chromium/components/keyed_service/core/keyed_service.cc b/chromium/components/keyed_service/core/keyed_service.cc
new file mode 100644
index 00000000000..5cfd61d3366
--- /dev/null
+++ b/chromium/components/keyed_service/core/keyed_service.cc
@@ -0,0 +1,11 @@
+// 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/keyed_service/core/keyed_service.h"
+
+KeyedService::KeyedService() {}
+
+KeyedService::~KeyedService() {}
+
+void KeyedService::Shutdown() {}
diff --git a/chromium/components/keyed_service/core/keyed_service.h b/chromium/components/keyed_service/core/keyed_service.h
new file mode 100644
index 00000000000..ad5b529b56d
--- /dev/null
+++ b/chromium/components/keyed_service/core/keyed_service.h
@@ -0,0 +1,27 @@
+// 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_KEYED_SERVICE_CORE_KEYED_SERVICE_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_H_
+
+#include "components/keyed_service/core/keyed_service_export.h"
+
+// Interface for keyed services that support two-phase destruction order.
+//
+// Two-phase shutdown allows keyed services to have a first pass shutdown phase
+// where they drop references. Not all services will need this, so there's a
+// default implementation. Only once every service has been given a chance to
+// drop references are services deleted.
+class KEYED_SERVICE_EXPORT KeyedService {
+ public:
+ KeyedService();
+
+ // The first pass is to call Shutdown on a KeyedService.
+ virtual void Shutdown();
+
+ // The second pass is the actual deletion of each object.
+ virtual ~KeyedService();
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_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
new file mode 100644
index 00000000000..20ef2104af5
--- /dev/null
+++ b/chromium/components/keyed_service/core/keyed_service_base_factory.cc
@@ -0,0 +1,136 @@
+// 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/keyed_service/core/keyed_service_base_factory.h"
+
+#include "base/prefs/pref_service.h"
+#include "base/supports_user_data.h"
+#include "base/trace_event/trace_event.h"
+#include "components/keyed_service/core/dependency_manager.h"
+#include "components/pref_registry/pref_registry_syncable.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)
+ : dependency_manager_(manager) {
+#ifndef NDEBUG
+ service_name_ = service_name;
+#endif
+ dependency_manager_->AddComponent(this);
+}
+
+KeyedServiceBaseFactory::~KeyedServiceBaseFactory() {
+ dependency_manager_->RemoveComponent(this);
+}
+
+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(GetContextForDependencyManager(context));
+ user_prefs::PrefRegistrySyncable* registry =
+ static_cast<user_prefs::PrefRegistrySyncable*>(
+ prefs->DeprecatedGetPrefRegistry());
+ return registry;
+}
+
+#ifndef NDEBUG
+void KeyedServiceBaseFactory::AssertContextWasntDestroyed(
+ base::SupportsUserData* context) const {
+ DCHECK(CalledOnValidThread());
+ context = GetContextForDependencyManager(context);
+ dependency_manager_->AssertContextWasntDestroyed(context);
+}
+
+void KeyedServiceBaseFactory::MarkContextLiveForTesting(
+ base::SupportsUserData* context) {
+ DCHECK(CalledOnValidThread());
+ context = GetContextForDependencyManager(context);
+ dependency_manager_->MarkContextLiveForTesting(context);
+}
+#endif
+
+bool KeyedServiceBaseFactory::ServiceIsCreatedWithContext() const {
+ return false;
+}
+
+bool KeyedServiceBaseFactory::ServiceIsNULLWhileTesting() const {
+ return false;
+}
+
+void KeyedServiceBaseFactory::ContextDestroyed(
+ base::SupportsUserData* context) {
+ // While object destruction can be customized in ways where the object is
+ // only dereferenced, this still must run on the UI thread.
+ DCHECK(CalledOnValidThread());
+ 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);
+}
+
+#if defined(OS_IOS)
+base::SupportsUserData* KeyedServiceBaseFactory::GetTypedContext(
+ base::SupportsUserData* context) const {
+ return context;
+}
+
+base::SupportsUserData* KeyedServiceBaseFactory::GetContextForDependencyManager(
+ base::SupportsUserData* context) const {
+ return context;
+}
+#endif // defined(OS_IOS)
diff --git a/chromium/components/keyed_service/core/keyed_service_base_factory.h b/chromium/components/keyed_service/core/keyed_service_base_factory.h
new file mode 100644
index 00000000000..a9ea21feb79
--- /dev/null
+++ b/chromium/components/keyed_service/core/keyed_service_base_factory.h
@@ -0,0 +1,197 @@
+// 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_KEYED_SERVICE_CORE_KEYED_SERVICE_BASE_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_BASE_FACTORY_H_
+
+#include <set>
+
+#include "base/threading/non_thread_safe.h"
+#include "components/keyed_service/core/dependency_node.h"
+#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.
+//
+// This object describes general dependency management between factories while
+// direct subclasses react to lifecycle events and implement memory management.
+class KEYED_SERVICE_EXPORT KeyedServiceBaseFactory
+ : public base::NonThreadSafe,
+ NON_EXPORTED_BASE(public DependencyNode) {
+ public:
+#ifndef NDEBUG
+ // Returns our name. We don't keep track of this in release mode.
+ const char* name() const { return service_name_; }
+#endif
+
+ protected:
+ 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);
+
+#ifndef NDEBUG
+ // Debugging assertion that will NOTREACHED() is |context| is considered
+ // stale. Should be used by subclasses when accessing |context|.
+ void AssertContextWasntDestroyed(base::SupportsUserData* 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 am instance from a prior test (i.e., 0xWhatever might
+ // be created, be destroyed, and then a new object might be created at
+ // 0xWhatever).
+ void MarkContextLiveForTesting(base::SupportsUserData* context);
+#endif
+
+ // 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;
+
+ // Finds which context (if any) to use.
+ virtual base::SupportsUserData* GetContextToUse(
+ base::SupportsUserData* 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
+ // context is created and should override this method to return true.
+ virtual bool ServiceIsCreatedWithContext() const;
+
+ // By default, testing contexts will be treated like normal contexts. If this
+ // method is overriden to return true, then the service associated with the
+ // testing context will be null.
+ virtual bool ServiceIsNULLWhileTesting() const;
+
+ // The service build by the factories goes through a two phase shutdown.
+ // It is up to the individual factory types to determine what this two pass
+ // shutdown means. The general framework guarantees the following:
+ //
+ // - Each ContextShutdown() is called in dependency order (and you may
+ // reach out to other services during this phase).
+ //
+ // - Each ContextDestroyed() is called in dependency order. Accessing a
+ // 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);
+
+ // The iOS code downstream used BrowserContextKeyedServiceFactories. The code
+ // is currently ported to use BrowserStateKeyedServiceFactories instead but
+ // has to support mixed dependencies to ease the migration — which can then
+ // be done incrementally. This means that on iOS the DependencyManager can
+ // reference both type of factories and the context need to be converted to
+ // the correct typed context.
+ //
+ // GetTypedContext()/GetContextForDependencyManager() are there to supports
+ // the mixed dependencies. On all platform except iOS they are pass-through
+ // and returns the original object. On iOS, they convert the context to resp.
+ // web::BrowserState/content::BrowserContext casted as base::SupportsUserData.
+ //
+ // TODO(ios): migration is tracked by http://crbug.com/478763 and those two
+ // methods (and their *Internal implementation) must be removed once migration
+ // is complete.
+
+ // Returns the correctly typed context for the KeyedServiceFactory (either a
+ // content::BrowserContext for BrowserContextKeyedServiceFactory or a
+ // web::BrowserState for a BrowserStateKeyedServiceFactory) when using mixed
+ // dependency (iOS). Simple pass-through on all other platforms.
+ //
+ // TODO(ios): remove this method and its call-sites once iOS only uses
+ // BrowserStateKeyedServiceFactories, http://crbug.com/478763
+#if defined(OS_IOS)
+ virtual base::SupportsUserData* GetTypedContext(
+ base::SupportsUserData* context) const;
+#else
+ base::SupportsUserData* GetTypedContext(
+ base::SupportsUserData* context) const {
+ return context;
+ }
+#endif // defined(OS_IOS)
+
+ // Returns the content::BrowserContext associated to |context| for interaction
+ // with the DependencyManager when using mixed dependency (iOS). Simple pass-
+ // through on all other platforms.
+ //
+ // TODO(ios): remove this method and its call-sites once iOS only uses
+ // BrowserStateKeyedServiceFactories, http://crbug.com/478763
+#if defined(OS_IOS)
+ virtual base::SupportsUserData* GetContextForDependencyManager(
+ base::SupportsUserData* context) const;
+#else
+ base::SupportsUserData* GetContextForDependencyManager(
+ base::SupportsUserData* context) const {
+ return context;
+ }
+#endif // defined(OS_IOS)
+
+ private:
+ friend class DependencyManager;
+
+ // The DependencyManager used. In real code, this will be a singleton used
+ // 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.
+ 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;
+
+ // Returns true if a testing factory function has been set for |context|.
+ virtual bool HasTestingFactory(base::SupportsUserData* 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_;
+
+#if !defined(NDEBUG)
+ // A static string passed in to the constructor. Should be unique across all
+ // services. This is used only for debugging in debug mode. (Used to print
+ // pretty graphs with GraphViz.)
+ const char* service_name_;
+#endif
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_BASE_FACTORY_H_
diff --git a/chromium/components/keyed_service/core/keyed_service_export.h b/chromium/components/keyed_service/core/keyed_service_export.h
new file mode 100644
index 00000000000..0938614b7b2
--- /dev/null
+++ b/chromium/components/keyed_service/core/keyed_service_export.h
@@ -0,0 +1,29 @@
+// 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_KEYED_SERVICE_CORE_KEYED_SERVICE_EXPORT_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(KEYED_SERVICE_IMPLEMENTATION)
+#define KEYED_SERVICE_EXPORT __declspec(dllexport)
+#else
+#define KEYED_SERVICE_EXPORT __declspec(dllimport)
+#endif // defined(KEYED_SERVICE_IMPLEMENTATION)
+
+#else // defined(WIN32)
+#if defined(KEYED_SERVICE_IMPLEMENTATION)
+#define KEYED_SERVICE_EXPORT __attribute__((visibility("default")))
+#else
+#define KEYED_SERVICE_EXPORT
+#endif
+#endif
+
+#else // defined(COMPONENT_BUILD)
+#define KEYED_SERVICE_EXPORT
+#endif
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_EXPORT_H_
diff --git a/chromium/components/keyed_service/core/keyed_service_factory.cc b/chromium/components/keyed_service/core/keyed_service_factory.cc
new file mode 100644
index 00000000000..efc61f904e7
--- /dev/null
+++ b/chromium/components/keyed_service/core/keyed_service_factory.cc
@@ -0,0 +1,139 @@
+// 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/keyed_service/core/keyed_service_factory.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "base/trace_event/trace_event.h"
+#include "components/keyed_service/core/dependency_manager.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+KeyedServiceFactory::KeyedServiceFactory(const char* name,
+ DependencyManager* manager)
+ : KeyedServiceBaseFactory(name, manager) {
+}
+
+KeyedServiceFactory::~KeyedServiceFactory() {
+ DCHECK(mapping_.empty());
+}
+
+void KeyedServiceFactory::SetTestingFactory(
+ base::SupportsUserData* context,
+ TestingFactoryFunction 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);
+
+#ifndef NDEBUG
+ // 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
+ // |AssertBrowserContextWasntDestroyed| to raise an error.
+ MarkContextLiveForTesting(context);
+#endif
+
+ // We have to go through the shutdown and destroy mechanisms because there
+ // are unit tests that create a service on a context and then change the
+ // testing service mid-test.
+ ContextShutdown(context);
+ ContextDestroyed(context);
+
+ if (add_context)
+ MarkPreferencesSetOn(context);
+
+ testing_factories_[context] = testing_factory;
+}
+
+KeyedService* KeyedServiceFactory::SetTestingFactoryAndUse(
+ base::SupportsUserData* context,
+ TestingFactoryFunction testing_factory) {
+ DCHECK(testing_factory);
+ SetTestingFactory(context, testing_factory);
+ return GetServiceForContext(context, true);
+}
+
+KeyedService* KeyedServiceFactory::GetServiceForContext(
+ base::SupportsUserData* context,
+ bool create) {
+ TRACE_EVENT0("browser,startup", "KeyedServiceFactory::GetServiceForContext");
+ context = GetContextToUse(context);
+ if (!context)
+ return nullptr;
+
+ // NOTE: If you modify any of the logic below, make sure to update the
+ // refcounted version in refcounted_context_keyed_service_factory.cc!
+ const auto& it = mapping_.find(context);
+ if (it != mapping_.end())
+ return it->second;
+
+ // Object not found.
+ if (!create)
+ return nullptr; // And we're forbidden from creating one.
+
+ // Create new object.
+ // Check to see if we have a per-context testing factory that we should use
+ // instead of default behavior.
+ scoped_ptr<KeyedService> service;
+ const auto& jt = testing_factories_.find(context);
+ if (jt != testing_factories_.end()) {
+ if (jt->second) {
+ if (!IsOffTheRecord(context))
+ RegisterUserPrefsOnContextForTest(context);
+ service = jt->second(context);
+ }
+ } else {
+ service = BuildServiceInstanceFor(context);
+ }
+
+ Associate(context, service.Pass());
+ return mapping_[context];
+}
+
+void KeyedServiceFactory::Associate(base::SupportsUserData* context,
+ scoped_ptr<KeyedService> service) {
+ DCHECK(!ContainsKey(mapping_, context));
+ mapping_.insert(std::make_pair(context, service.release()));
+}
+
+void KeyedServiceFactory::Disassociate(base::SupportsUserData* context) {
+ const auto& it = mapping_.find(context);
+ if (it != mapping_.end()) {
+ delete it->second;
+ mapping_.erase(it);
+ }
+}
+
+void KeyedServiceFactory::ContextShutdown(base::SupportsUserData* context) {
+ const auto& it = mapping_.find(context);
+ if (it != mapping_.end() && it->second)
+ it->second->Shutdown();
+}
+
+void KeyedServiceFactory::ContextDestroyed(base::SupportsUserData* context) {
+ Disassociate(context);
+
+ // For unit tests, we also remove the factory function both so we don't
+ // maintain a big map of dead pointers, but also since we may have a second
+ // object that lives at the same address (see other comments about unit tests
+ // in this file).
+ testing_factories_.erase(context);
+
+ KeyedServiceBaseFactory::ContextDestroyed(context);
+}
+
+void KeyedServiceFactory::SetEmptyTestingFactory(
+ base::SupportsUserData* context) {
+ SetTestingFactory(context, nullptr);
+}
+
+bool KeyedServiceFactory::HasTestingFactory(base::SupportsUserData* context) {
+ return testing_factories_.find(context) != testing_factories_.end();
+}
+
+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
new file mode 100644
index 00000000000..e2ef4b8b84b
--- /dev/null
+++ b/chromium/components/keyed_service/core/keyed_service_factory.h
@@ -0,0 +1,99 @@
+// 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_KEYED_SERVICE_CORE_KEYED_SERVICE_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_FACTORY_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/callback_forward.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/keyed_service/core/keyed_service_base_factory.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+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).
+//
+// 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 which services are depended on.
+class KEYED_SERVICE_EXPORT KeyedServiceFactory
+ : public KeyedServiceBaseFactory {
+ protected:
+ KeyedServiceFactory(const char* name, DependencyManager* manager);
+ ~KeyedServiceFactory() override;
+
+ // A function that supplies the instance of a KeyedService for a given
+ // |context|. This is used primarily for testing, where we want to feed
+ // a specific mock into the KeyedServiceFactory system.
+ typedef scoped_ptr<KeyedService>(*TestingFactoryFunction)(
+ base::SupportsUserData* context);
+
+ // Associates |factory| with |context| so that |factory| is used to create
+ // the KeyedService when requested. |factory| can be NULL to signal that
+ // KeyedService should be NULL. Multiple calls to SetTestingFactory() are
+ // allowed; previous services will be shut down.
+ void SetTestingFactory(base::SupportsUserData* context,
+ TestingFactoryFunction factory);
+
+ // Associates |factory| with |context| and immediately returns the created
+ // KeyedService. Since the factory will be used immediately, it may not be
+ // NULL.
+ KeyedService* SetTestingFactoryAndUse(base::SupportsUserData* context,
+ TestingFactoryFunction 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,
+ bool create);
+
+ // Maps |context| to |service| with debug checks to prevent duplication.
+ void Associate(base::SupportsUserData* context,
+ scoped_ptr<KeyedService> service);
+
+ // Removes the mapping from |context| to a service.
+ void Disassociate(base::SupportsUserData* context);
+
+ // Returns a new KeyedService that will be associated with |context|.
+ virtual scoped_ptr<KeyedService> BuildServiceInstanceFor(
+ base::SupportsUserData* context) const = 0;
+
+ // Returns whether the |context| is off-the-record or not.
+ virtual bool IsOffTheRecord(base::SupportsUserData* context) const = 0;
+
+ // KeyedServiceBaseFactory:
+ void ContextShutdown(base::SupportsUserData* context) override;
+ void ContextDestroyed(base::SupportsUserData* context) override;
+
+ void SetEmptyTestingFactory(base::SupportsUserData* context) override;
+ bool HasTestingFactory(base::SupportsUserData* context) override;
+ void CreateServiceNow(base::SupportsUserData* context) override;
+
+ private:
+ friend class DependencyManager;
+ friend class DependencyManagerUnittests;
+
+ typedef std::map<base::SupportsUserData*, KeyedService*> KeyedServices;
+ typedef std::map<base::SupportsUserData*, TestingFactoryFunction>
+ OverriddenTestingFunctions;
+
+ // The mapping between a context and its service.
+ KeyedServices mapping_;
+
+ // The mapping between a context and its overridden
+ // TestingFactoryFunction.
+ OverriddenTestingFunctions testing_factories_;
+
+ DISALLOW_COPY_AND_ASSIGN(KeyedServiceFactory);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_FACTORY_H_
diff --git a/chromium/components/keyed_service/core/keyed_service_shutdown_notifier.cc b/chromium/components/keyed_service/core/keyed_service_shutdown_notifier.cc
new file mode 100644
index 00000000000..cb0b27c482c
--- /dev/null
+++ b/chromium/components/keyed_service/core/keyed_service_shutdown_notifier.cc
@@ -0,0 +1,20 @@
+// 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/keyed_service/core/keyed_service_export.h"
+#include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
+
+KeyedServiceShutdownNotifier::KeyedServiceShutdownNotifier() {
+}
+KeyedServiceShutdownNotifier::~KeyedServiceShutdownNotifier() {
+}
+
+scoped_ptr<base::CallbackList<void()>::Subscription>
+KeyedServiceShutdownNotifier::Subscribe(const base::Closure& callback) {
+ return callback_list_.Add(callback);
+}
+
+void KeyedServiceShutdownNotifier::Shutdown() {
+ callback_list_.Notify();
+}
diff --git a/chromium/components/keyed_service/core/keyed_service_shutdown_notifier.h b/chromium/components/keyed_service/core/keyed_service_shutdown_notifier.h
new file mode 100644
index 00000000000..2f2ca294a76
--- /dev/null
+++ b/chromium/components/keyed_service/core/keyed_service_shutdown_notifier.h
@@ -0,0 +1,39 @@
+// 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_KEYED_SERVICE_CORE_KEYED_SERVICE_SHUTDOWN_NOTIFIER_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_SHUTDOWN_NOTIFIER_H_
+
+#include "base/callback_list.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+// This is a helper class for objects that depend on one or more keyed services,
+// but which cannot be keyed services themselves, for example because they don't
+// correspond 1:1 to a context, or because they have a different lifetime.
+//
+// To use this class, add a factory class and declare the dependencies there.
+// This class (being a KeyedService itself) will be shut down before its
+// dependencies and notify its observers.
+class KEYED_SERVICE_EXPORT KeyedServiceShutdownNotifier : public KeyedService {
+ public:
+ using Subscription = base::CallbackList<void()>::Subscription;
+
+ KeyedServiceShutdownNotifier();
+ ~KeyedServiceShutdownNotifier() override;
+
+ // Subscribe for a notification when the keyed services this object depends on
+ // (as defined by its factory) are shut down. The subscription object can be
+ // destroyed to unsubscribe.
+ scoped_ptr<Subscription> Subscribe(const base::Closure& callback);
+
+ private:
+ // KeyedService implementation:
+ void Shutdown() override;
+
+ base::CallbackList<void()> callback_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(KeyedServiceShutdownNotifier);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_SHUTDOWN_NOTIFIER_H_
diff --git a/chromium/components/keyed_service/core/refcounted_keyed_service.cc b/chromium/components/keyed_service/core/refcounted_keyed_service.cc
new file mode 100644
index 00000000000..d5ff3f94108
--- /dev/null
+++ b/chromium/components/keyed_service/core/refcounted_keyed_service.cc
@@ -0,0 +1,33 @@
+// 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/keyed_service/core/refcounted_keyed_service.h"
+
+#include "base/location.h"
+#include "base/thread_task_runner_handle.h"
+
+namespace impl {
+
+// static
+void RefcountedKeyedServiceTraits::Destruct(const RefcountedKeyedService* obj) {
+ if (obj->task_runner_.get() != nullptr &&
+ obj->task_runner_.get() != base::ThreadTaskRunnerHandle::Get()) {
+ obj->task_runner_->DeleteSoon(FROM_HERE, obj);
+ } else {
+ delete obj;
+ }
+}
+
+} // namespace impl
+
+RefcountedKeyedService::RefcountedKeyedService() : task_runner_(nullptr) {
+}
+
+RefcountedKeyedService::RefcountedKeyedService(
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
+ : task_runner_(task_runner) {
+}
+
+RefcountedKeyedService::~RefcountedKeyedService() {
+}
diff --git a/chromium/components/keyed_service/core/refcounted_keyed_service.h b/chromium/components/keyed_service/core/refcounted_keyed_service.h
new file mode 100644
index 00000000000..31815d6f8ff
--- /dev/null
+++ b/chromium/components/keyed_service/core/refcounted_keyed_service.h
@@ -0,0 +1,72 @@
+// 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_KEYED_SERVICE_CORE_REFCOUNTED_KEYED_SERVICE_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_REFCOUNTED_KEYED_SERVICE_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner_helpers.h"
+#include "base/single_thread_task_runner.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+class RefcountedKeyedService;
+
+namespace impl {
+
+struct KEYED_SERVICE_EXPORT RefcountedKeyedServiceTraits {
+ static void Destruct(const RefcountedKeyedService* obj);
+};
+
+} // namespace impl
+
+// Base class for refcounted objects that hang off the BrowserContext.
+//
+// The two pass shutdown described in KeyedService works a bit differently
+// because there could be outstanding references on other threads.
+// ShutdownOnUIThread() will be called on the UI thread, and then the
+// destructor will run when the last reference is dropped, which may or may not
+// be after the corresponding BrowserContext has been destroyed.
+//
+// Optionally, if you initialize your service with the constructor that takes a
+// single thread task runner, your service will be deleted on that thread. We
+// can't use content::DeleteOnThread<> directly because RefcountedKeyedService
+// must not depend on //content.
+class KEYED_SERVICE_EXPORT RefcountedKeyedService
+ : public base::RefCountedThreadSafe<RefcountedKeyedService,
+ impl::RefcountedKeyedServiceTraits> {
+ public:
+ // Unlike KeyedService, ShutdownOnUI is not optional. You must do something
+ // to drop references during the first pass Shutdown() because this is the
+ // only point where you are guaranteed that something is running on the UI
+ // thread. The PKSF framework will ensure that this is only called on the UI
+ // thread; you do not need to check for that yourself.
+ virtual void ShutdownOnUIThread() = 0;
+
+ protected:
+ // If your service does not need to be deleted on a specific thread, use the
+ // default constructor.
+ RefcountedKeyedService();
+
+ // If you need your service to be deleted on a specific thread (for example,
+ // you're converting a service that used content::DeleteOnThread<IO>), then
+ // use this constructor with a reference to the SingleThreadTaskRunner (you
+ // can get it from content::BrowserThread::GetMessageLoopProxyForThread).
+ explicit RefcountedKeyedService(
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
+
+ // The second pass destruction can happen anywhere unless you specify which
+ // thread this service must be destroyed on by using the second constructor.
+ virtual ~RefcountedKeyedService();
+
+ private:
+ friend struct impl::RefcountedKeyedServiceTraits;
+ friend class base::DeleteHelper<RefcountedKeyedService>;
+ friend class base::RefCountedThreadSafe<RefcountedKeyedService,
+ impl::RefcountedKeyedServiceTraits>;
+
+ // Do we have to delete this object on a specific thread?
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_REFCOUNTED_KEYED_SERVICE_H_
diff --git a/chromium/components/keyed_service/core/refcounted_keyed_service_factory.cc b/chromium/components/keyed_service/core/refcounted_keyed_service_factory.cc
new file mode 100644
index 00000000000..d33340b2d53
--- /dev/null
+++ b/chromium/components/keyed_service/core/refcounted_keyed_service_factory.cc
@@ -0,0 +1,131 @@
+// 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/keyed_service/core/refcounted_keyed_service_factory.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "components/keyed_service/core/dependency_manager.h"
+#include "components/keyed_service/core/refcounted_keyed_service.h"
+
+RefcountedKeyedServiceFactory::RefcountedKeyedServiceFactory(
+ const char* name,
+ DependencyManager* manager)
+ : KeyedServiceBaseFactory(name, manager) {
+}
+
+RefcountedKeyedServiceFactory::~RefcountedKeyedServiceFactory() {
+ DCHECK(mapping_.empty());
+}
+
+void RefcountedKeyedServiceFactory::SetTestingFactory(
+ base::SupportsUserData* context,
+ TestingFactoryFunction 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);
+
+ // We have to go through the shutdown and destroy mechanisms because there
+ // are unit tests that create a service on a context and then change the
+ // testing service mid-test.
+ ContextShutdown(context);
+ ContextDestroyed(context);
+
+ if (add_context)
+ MarkPreferencesSetOn(context);
+
+ testing_factories_[context] = testing_factory;
+}
+
+scoped_refptr<RefcountedKeyedService>
+RefcountedKeyedServiceFactory::SetTestingFactoryAndUse(
+ base::SupportsUserData* context,
+ TestingFactoryFunction testing_factory) {
+ DCHECK(testing_factory);
+ SetTestingFactory(context, testing_factory);
+ return GetServiceForContext(context, true);
+}
+
+scoped_refptr<RefcountedKeyedService>
+RefcountedKeyedServiceFactory::GetServiceForContext(
+ base::SupportsUserData* context,
+ bool create) {
+ context = GetContextToUse(context);
+ if (!context)
+ return nullptr;
+
+ // NOTE: If you modify any of the logic below, make sure to update the
+ // non-refcounted version in context_keyed_service_factory.cc!
+ const auto& it = mapping_.find(context);
+ if (it != mapping_.end())
+ return it->second;
+
+ // Object not found.
+ if (!create)
+ return nullptr; // And we're forbidden from creating one.
+
+ // Create new object.
+ // Check to see if we have a per-BrowserContext testing factory that we should
+ // use instead of default behavior.
+ scoped_refptr<RefcountedKeyedService> service;
+ const auto& jt = testing_factories_.find(context);
+ if (jt != testing_factories_.end()) {
+ if (jt->second) {
+ if (!IsOffTheRecord(context))
+ RegisterUserPrefsOnContextForTest(context);
+ service = jt->second(context);
+ }
+ } else {
+ service = BuildServiceInstanceFor(context);
+ }
+
+ Associate(context, service);
+ return service;
+}
+
+void RefcountedKeyedServiceFactory::Associate(
+ base::SupportsUserData* context,
+ const scoped_refptr<RefcountedKeyedService>& service) {
+ DCHECK(!ContainsKey(mapping_, context));
+ mapping_.insert(std::make_pair(context, service));
+}
+
+void RefcountedKeyedServiceFactory::ContextShutdown(
+ base::SupportsUserData* context) {
+ const auto& it = mapping_.find(context);
+ if (it != mapping_.end() && it->second.get())
+ it->second->ShutdownOnUIThread();
+}
+
+void RefcountedKeyedServiceFactory::ContextDestroyed(
+ base::SupportsUserData* context) {
+ // We "merely" drop our reference to the service. Hopefully this will cause
+ // the service to be destroyed. If not, oh well.
+ mapping_.erase(context);
+
+ // For unit tests, we also remove the factory function both so we don't
+ // maintain a big map of dead pointers, but also since we may have a second
+ // object that lives at the same address (see other comments about unit tests
+ // in this file).
+ testing_factories_.erase(context);
+
+ KeyedServiceBaseFactory::ContextDestroyed(context);
+}
+
+void RefcountedKeyedServiceFactory::SetEmptyTestingFactory(
+ base::SupportsUserData* context) {
+ SetTestingFactory(context, nullptr);
+}
+
+bool RefcountedKeyedServiceFactory::HasTestingFactory(
+ base::SupportsUserData* context) {
+ return testing_factories_.find(context) != testing_factories_.end();
+}
+
+void RefcountedKeyedServiceFactory::CreateServiceNow(
+ base::SupportsUserData* context) {
+ GetServiceForContext(context, 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
new file mode 100644
index 00000000000..de8b3b4b98a
--- /dev/null
+++ b/chromium/components/keyed_service/core/refcounted_keyed_service_factory.h
@@ -0,0 +1,96 @@
+// 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_KEYED_SERVICE_CORE_REFCOUNTED_KEYED_SERVICE_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_REFCOUNTED_KEYED_SERVICE_FACTORY_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "components/keyed_service/core/keyed_service_base_factory.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+class RefcountedKeyedService;
+
+// A specialized KeyedServiceBaseFactory that manages a RefcountedThreadSafe<>.
+//
+// While the factory returns RefcountedThreadSafe<>s, the factory itself is a
+// base::NotThreadSafe. Only call methods on this object on the UI thread.
+//
+// Implementers of RefcountedKeyedService should note that we guarantee that
+// ShutdownOnUIThread() is called on the UI thread, but actual object
+// destruction can happen anywhere.
+class KEYED_SERVICE_EXPORT RefcountedKeyedServiceFactory
+ : public KeyedServiceBaseFactory {
+ protected:
+ RefcountedKeyedServiceFactory(const char* name, DependencyManager* manager);
+ ~RefcountedKeyedServiceFactory() override;
+
+ // A function that supplies the instance of a KeyedService for a given
+ // |context|. This is used primarily for testing, where we want to feed
+ // a specific mock into the KeyedServiceFactory system.
+ typedef scoped_refptr<RefcountedKeyedService>(*TestingFactoryFunction)(
+ base::SupportsUserData* context);
+
+ // Associates |factory| with |context| so that |factory| is used to create
+ // the KeyedService when requested. |factory| can be NULL to signal that
+ // KeyedService should be NULL. Multiple calls to SetTestingFactory() are
+ // allowed; previous services will be shut down.
+ void SetTestingFactory(base::SupportsUserData* context,
+ TestingFactoryFunction factory);
+
+ // Associates |factory| with |context| and immediately returns the created
+ // KeyedService. Since the factory will be used immediately, it may not be
+ // NULL.
+ scoped_refptr<RefcountedKeyedService> SetTestingFactoryAndUse(
+ base::SupportsUserData* context,
+ TestingFactoryFunction 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);
+
+ // Maps |context| to |service| with debug checks to prevent duplication.
+ void Associate(base::SupportsUserData* context,
+ const scoped_refptr<RefcountedKeyedService>& service);
+
+ // Returns a new RefcountedKeyedService that will be associated with
+ // |context|.
+ virtual scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
+ base::SupportsUserData* context) const = 0;
+
+ // Returns whether the |context| is off-the-record or not.
+ virtual bool IsOffTheRecord(base::SupportsUserData* context) const = 0;
+
+ // KeyedServiceBaseFactory:
+ void ContextShutdown(base::SupportsUserData* context) override;
+ void ContextDestroyed(base::SupportsUserData* context) override;
+
+ void SetEmptyTestingFactory(base::SupportsUserData* context) override;
+ bool HasTestingFactory(base::SupportsUserData* context) override;
+ void CreateServiceNow(base::SupportsUserData* context) override;
+
+ private:
+ typedef std::map<base::SupportsUserData*,
+ scoped_refptr<RefcountedKeyedService>> KeyedServices;
+ typedef std::map<base::SupportsUserData*, TestingFactoryFunction>
+ OverriddenTestingFunctions;
+
+ // The mapping between a context and its refcounted service.
+ KeyedServices mapping_;
+
+ // The mapping between a context and its overridden
+ // TestingFactoryFunction.
+ OverriddenTestingFunctions testing_factories_;
+
+ DISALLOW_COPY_AND_ASSIGN(RefcountedKeyedServiceFactory);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_REFCOUNTED_KEYED_SERVICE_FACTORY_H_
diff --git a/chromium/components/keyed_service/core/service_access_type.h b/chromium/components/keyed_service/core/service_access_type.h
new file mode 100644
index 00000000000..257a47d5d4c
--- /dev/null
+++ b/chromium/components/keyed_service/core/service_access_type.h
@@ -0,0 +1,34 @@
+// 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_KEYED_SERVICE_CORE_SERVICE_ACCESS_TYPE_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_SERVICE_ACCESS_TYPE_H_
+
+// Some KeyedServices are accessed with the following parameter. This parameter
+// defines what the caller plans to do with the service.
+//
+// The caller is responsible for not performing any operation that would
+// result in persistent implicit records while using an OffTheRecord context.
+// This flag allows the context to perform an additional check.
+//
+// It also leaves an opportunity to perform further checks in the future. For
+// example an history service that only allow some specific methods could be
+// returned.
+enum class ServiceAccessType {
+ // The caller plans to perform a read or write that takes place as a result
+ // of the user input. Use this flag when the operation can be performed while
+ // incognito (for example creating a bookmark).
+ //
+ // Since EXPLICIT_ACCESS means "as a result of a user action", this request
+ // always succeeds.
+ EXPLICIT_ACCESS,
+
+ // The caller plans to call a method that will permanently change some data
+ // in the context, as part of Chrome's implicit data logging. Use this flag
+ // before performing an operation which is incompatible with the incognito
+ // mode.
+ IMPLICIT_ACCESS
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_SERVICE_ACCESS_TYPE_H_
diff --git a/chromium/components/keyed_service/ios/DEPS b/chromium/components/keyed_service/ios/DEPS
new file mode 100644
index 00000000000..0fc0ddddacd
--- /dev/null
+++ b/chromium/components/keyed_service/ios/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+ios/web/public",
+]
diff --git a/chromium/components/keyed_service/ios/OWNERS b/chromium/components/keyed_service/ios/OWNERS
new file mode 100644
index 00000000000..e5e0273a38c
--- /dev/null
+++ b/chromium/components/keyed_service/ios/OWNERS
@@ -0,0 +1,3 @@
+droger@chromium.org
+sdefresne@chromium.org
+stuartmorgan@chromium.org
diff --git a/chromium/components/keyed_service/ios/browser_state_context_converter.cc b/chromium/components/keyed_service/ios/browser_state_context_converter.cc
new file mode 100644
index 00000000000..608bb559b5e
--- /dev/null
+++ b/chromium/components/keyed_service/ios/browser_state_context_converter.cc
@@ -0,0 +1,28 @@
+// 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/keyed_service/ios/browser_state_context_converter.h"
+
+namespace {
+
+// Global BrowserStateContextConverter* instance, may be null.
+BrowserStateContextConverter* g_browser_state_context_converter = nullptr;
+
+} // namespace
+
+// static
+void BrowserStateContextConverter::SetInstance(
+ BrowserStateContextConverter* instance) {
+ g_browser_state_context_converter = instance;
+}
+
+BrowserStateContextConverter* BrowserStateContextConverter::GetInstance() {
+ return g_browser_state_context_converter;
+}
+
+BrowserStateContextConverter::BrowserStateContextConverter() {
+}
+
+BrowserStateContextConverter::~BrowserStateContextConverter() {
+}
diff --git a/chromium/components/keyed_service/ios/browser_state_context_converter.h b/chromium/components/keyed_service/ios/browser_state_context_converter.h
new file mode 100644
index 00000000000..7af647d4f41
--- /dev/null
+++ b/chromium/components/keyed_service/ios/browser_state_context_converter.h
@@ -0,0 +1,55 @@
+// 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_KEYED_SERVICE_IOS_BROWSER_STATE_CONTEXT_CONVERTER_H_
+#define COMPONENTS_KEYED_SERVICE_IOS_BROWSER_STATE_CONTEXT_CONVERTER_H_
+
+#include "base/macros.h"
+
+namespace base {
+class SupportsUserData;
+}
+
+// BrowserStateContextConverter does safe conversion of base::SupportsUserData*
+// to web::BrowserState* or content::BrowserContext*.
+//
+// iOS code is still using BrowserContextKeyedServiceFactory and until the
+// conversion is complete — http://crbug.com/478763 — there is need to have
+// mixed dependency between BCKSF and BSKSF.
+//
+// The implementation has BrowserStateKeyedServiceFactory supporting a
+// BrowserContextDependencyManager as DependencyManager. Thus the context
+// parameter passed to the BrowserStateKeyedServiceFactory can either be
+// content::BrowserContext if the method is invoked by DependencyManager
+// or web::BrowserState if the method is invoked via the type-safe public
+// API.
+//
+// The public API of BrowserStateKeyedServiceFactory is type-safe (all
+// public method receive web::BrowserState for context object), so only
+// methods that take a base::SupportsUserData need to discriminate
+// between the two objects.
+class BrowserStateContextConverter {
+ public:
+ // Sets/Gets the global BrowserStateContextConverter instance. May return null
+ // when mixed dependencies are disabled.
+ static void SetInstance(BrowserStateContextConverter* instance);
+ static BrowserStateContextConverter* GetInstance();
+
+ // Converts |context| to a web::BrowserState* and returns it casted as a
+ // base::SupportsUserData*.
+ virtual base::SupportsUserData* GetBrowserStateForContext(
+ base::SupportsUserData* context) = 0;
+ // Converts |context| to a content::BrowserContext* and returns it casted as a
+ // base::SupportsUserData*.
+ virtual base::SupportsUserData* GetBrowserContextForContext(
+ base::SupportsUserData* context) = 0;
+
+ protected:
+ BrowserStateContextConverter();
+ virtual ~BrowserStateContextConverter();
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserStateContextConverter);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_IOS_BROWSER_STATE_CONTEXT_CONVERTER_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
new file mode 100644
index 00000000000..fb313ae3d99
--- /dev/null
+++ b/chromium/components/keyed_service/ios/browser_state_dependency_manager.cc
@@ -0,0 +1,67 @@
+// 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/keyed_service/ios/browser_state_dependency_manager.h"
+
+#include "base/memory/singleton.h"
+#include "base/trace_event/trace_event.h"
+#include "ios/web/public/browser_state.h"
+
+// static
+BrowserStateDependencyManager* BrowserStateDependencyManager::GetInstance() {
+ return base::Singleton<BrowserStateDependencyManager>::get();
+}
+
+void BrowserStateDependencyManager::RegisterBrowserStatePrefsForServices(
+ web::BrowserState* context,
+ user_prefs::PrefRegistrySyncable* pref_registry) {
+ RegisterPrefsForServices(context, pref_registry);
+}
+
+void BrowserStateDependencyManager::CreateBrowserStateServices(
+ web::BrowserState* context) {
+ DoCreateBrowserStateServices(context, false);
+}
+
+void BrowserStateDependencyManager::CreateBrowserStateServicesForTest(
+ web::BrowserState* context) {
+ DoCreateBrowserStateServices(context, true);
+}
+
+void BrowserStateDependencyManager::DestroyBrowserStateServices(
+ web::BrowserState* context) {
+ DependencyManager::DestroyContextServices(context);
+}
+
+#ifndef NDEBUG
+void BrowserStateDependencyManager::AssertBrowserStateWasntDestroyed(
+ web::BrowserState* context) {
+ DependencyManager::AssertContextWasntDestroyed(context);
+}
+
+void BrowserStateDependencyManager::MarkBrowserStateLiveForTesting(
+ web::BrowserState* context) {
+ DependencyManager::MarkContextLiveForTesting(context);
+}
+#endif // NDEBUG
+
+BrowserStateDependencyManager::BrowserStateDependencyManager() {
+}
+
+BrowserStateDependencyManager::~BrowserStateDependencyManager() {
+}
+
+void BrowserStateDependencyManager::DoCreateBrowserStateServices(
+ web::BrowserState* context,
+ bool is_testing_context) {
+ TRACE_EVENT0("browser",
+ "BrowserStateDependencyManager::DoCreateBrowserStateServices")
+ DependencyManager::CreateContextServices(context, is_testing_context);
+}
+
+#ifndef NDEBUG
+void BrowserStateDependencyManager::DumpContextDependencies(
+ base::SupportsUserData* 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
new file mode 100644
index 00000000000..649f16f2376
--- /dev/null
+++ b/chromium/components/keyed_service/ios/browser_state_dependency_manager.h
@@ -0,0 +1,91 @@
+// 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_KEYED_SERVICE_IOS_BROWSER_STATE_DEPENDENCY_MANAGER_H_
+#define COMPONENTS_KEYED_SERVICE_IOS_BROWSER_STATE_DEPENDENCY_MANAGER_H_
+
+#include "base/callback_forward.h"
+#include "base/callback_list.h"
+#include "base/macros.h"
+#include "components/keyed_service/core/dependency_manager.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+} // namespace base
+
+namespace web {
+class BrowserState;
+}
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+// A singleton that listens for context destruction notifications and
+// rebroadcasts them to each KeyedServiceBaseFactory in a safe order
+// based on the stated dependencies by each service.
+class KEYED_SERVICE_EXPORT BrowserStateDependencyManager
+ : public DependencyManager {
+ public:
+ static BrowserStateDependencyManager* GetInstance();
+
+ // Registers context-specific preferences for all services via |registry|.
+ // |context| should be the BrowserState containing |registry| and is used as
+ // a key to prevent multiple registrations on the same BrowserState in
+ // tests.
+ void RegisterBrowserStatePrefsForServices(
+ web::BrowserState* context,
+ user_prefs::PrefRegistrySyncable* registry);
+
+ // Called by each BrowserState to alert us of its creation. Service that
+ // want to be started when BrowserState is created should override the
+ // ServiceIsCreatedWithBrowserState() method in their factory. Preferences
+ // registration also happens during that method call.
+ void CreateBrowserStateServices(web::BrowserState* context);
+
+ // Similar to CreateBrowserStateServices(), except this is used for creating
+ // test BrowserStates - these contexts will not create services for any
+ // BrowserStateKeyedBaseFactories that return true from
+ // ServiceIsNULLWhileTesting().
+ void CreateBrowserStateServicesForTest(web::BrowserState* context);
+
+ // Called by each BrowserState to alert us that we should destroy services
+ // associated with it.
+ void DestroyBrowserStateServices(web::BrowserState* context);
+
+#ifndef NDEBUG
+ // Debugging assertion called as part of GetServiceForBrowserState in debug
+ // mode. This will NOTREACHED() whenever the user is trying to access a stale
+ // BrowserState*.
+ void AssertBrowserStateWasntDestroyed(web::BrowserState* context);
+
+ // Marks |context| as live (i.e., not stale). This method can be called as a
+ // safeguard against |AssertBrowserStateWasntDestroyed()| checks going off
+ // due to |context| aliasing a BrowserState instance from a prior test
+ // (i.e., 0xWhatever might be created, be destroyed, and then a new
+ // BrowserState object might be created at 0xWhatever).
+ void MarkBrowserStateLiveForTesting(web::BrowserState* context);
+#endif // NDEBUG
+
+ private:
+ friend struct base::DefaultSingletonTraits<BrowserStateDependencyManager>;
+
+ BrowserStateDependencyManager();
+ ~BrowserStateDependencyManager() override;
+
+ // Helper function used by CreateBrowserStateServices[ForTest].
+ void DoCreateBrowserStateServices(web::BrowserState* context,
+ bool is_testing_context);
+
+#ifndef NDEBUG
+ // DependencyManager:
+ void DumpContextDependencies(base::SupportsUserData* context) const final;
+#endif // NDEBUG
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserStateDependencyManager);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_IOS_BROWSER_STATE_DEPENDENCY_MANAGER_H_
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
new file mode 100644
index 00000000000..4588febab30
--- /dev/null
+++ b/chromium/components/keyed_service/ios/browser_state_keyed_service_factory.cc
@@ -0,0 +1,139 @@
+// 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/keyed_service/ios/browser_state_keyed_service_factory.h"
+
+#include "base/logging.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "components/keyed_service/ios/browser_state_context_converter.h"
+#include "components/keyed_service/ios/browser_state_dependency_manager.h"
+#include "ios/web/public/browser_state.h"
+
+void BrowserStateKeyedServiceFactory::SetTestingFactory(
+ web::BrowserState* context,
+ TestingFactoryFunction testing_factory) {
+ KeyedServiceFactory::SetTestingFactory(
+ context, reinterpret_cast<KeyedServiceFactory::TestingFactoryFunction>(
+ testing_factory));
+}
+
+KeyedService* BrowserStateKeyedServiceFactory::SetTestingFactoryAndUse(
+ web::BrowserState* context,
+ TestingFactoryFunction testing_factory) {
+ return KeyedServiceFactory::SetTestingFactoryAndUse(
+ context, reinterpret_cast<KeyedServiceFactory::TestingFactoryFunction>(
+ testing_factory));
+}
+
+BrowserStateKeyedServiceFactory::BrowserStateKeyedServiceFactory(
+ const char* name,
+ /*BrowserState*/DependencyManager* manager)
+ : KeyedServiceFactory(name, manager) {
+}
+
+BrowserStateKeyedServiceFactory::~BrowserStateKeyedServiceFactory() {
+}
+
+KeyedService* BrowserStateKeyedServiceFactory::GetServiceForBrowserState(
+ web::BrowserState* context,
+ bool create) {
+ return KeyedServiceFactory::GetServiceForContext(context, create);
+}
+
+web::BrowserState* BrowserStateKeyedServiceFactory::GetBrowserStateToUse(
+ web::BrowserState* context) const {
+ DCHECK(CalledOnValidThread());
+
+#ifndef NDEBUG
+ AssertContextWasntDestroyed(context);
+#endif
+
+ // Safe default for Incognito mode: no service.
+ if (context->IsOffTheRecord())
+ return nullptr;
+
+ return context;
+}
+
+bool BrowserStateKeyedServiceFactory::ServiceIsCreatedWithBrowserState() const {
+ return KeyedServiceBaseFactory::ServiceIsCreatedWithContext();
+}
+
+bool BrowserStateKeyedServiceFactory::ServiceIsNULLWhileTesting() const {
+ return KeyedServiceBaseFactory::ServiceIsNULLWhileTesting();
+}
+
+void BrowserStateKeyedServiceFactory::BrowserStateShutdown(
+ web::BrowserState* context) {
+ KeyedServiceFactory::ContextShutdown(context);
+}
+
+void BrowserStateKeyedServiceFactory::BrowserStateDestroyed(
+ web::BrowserState* context) {
+ KeyedServiceFactory::ContextDestroyed(context);
+}
+
+scoped_ptr<KeyedService>
+BrowserStateKeyedServiceFactory::BuildServiceInstanceFor(
+ base::SupportsUserData* context) const {
+ return BuildServiceInstanceFor(static_cast<web::BrowserState*>(context));
+}
+
+bool BrowserStateKeyedServiceFactory::IsOffTheRecord(
+ base::SupportsUserData* context) const {
+ return static_cast<web::BrowserState*>(context)->IsOffTheRecord();
+}
+
+#if defined(OS_IOS)
+base::SupportsUserData* BrowserStateKeyedServiceFactory::GetTypedContext(
+ base::SupportsUserData* context) const {
+ if (context) {
+ BrowserStateContextConverter* context_converter =
+ BrowserStateContextConverter::GetInstance();
+ if (context_converter) {
+ context = context_converter->GetBrowserStateForContext(context);
+ DCHECK(context);
+ }
+ }
+ return context;
+}
+
+base::SupportsUserData*
+BrowserStateKeyedServiceFactory::GetContextForDependencyManager(
+ base::SupportsUserData* context) const {
+ if (context) {
+ BrowserStateContextConverter* context_converter =
+ BrowserStateContextConverter::GetInstance();
+ if (context_converter) {
+ context = context_converter->GetBrowserContextForContext(context);
+ DCHECK(context);
+ }
+ }
+ return context;
+}
+#endif // defined(OS_IOS)
+
+base::SupportsUserData* BrowserStateKeyedServiceFactory::GetContextToUse(
+ base::SupportsUserData* context) const {
+ return GetBrowserStateToUse(static_cast<web::BrowserState*>(context));
+}
+
+bool BrowserStateKeyedServiceFactory::ServiceIsCreatedWithContext() const {
+ return ServiceIsCreatedWithBrowserState();
+}
+
+void BrowserStateKeyedServiceFactory::ContextShutdown(
+ base::SupportsUserData* context) {
+ BrowserStateShutdown(static_cast<web::BrowserState*>(context));
+}
+
+void BrowserStateKeyedServiceFactory::ContextDestroyed(
+ base::SupportsUserData* context) {
+ BrowserStateDestroyed(static_cast<web::BrowserState*>(context));
+}
+
+void BrowserStateKeyedServiceFactory::RegisterPrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ RegisterBrowserStatePrefs(registry);
+}
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
new file mode 100644
index 00000000000..10628758855
--- /dev/null
+++ b/chromium/components/keyed_service/ios/browser_state_keyed_service_factory.h
@@ -0,0 +1,140 @@
+// 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_KEYED_SERVICE_IOS_BROWSER_STATE_KEYED_SERVICE_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_IOS_BROWSER_STATE_KEYED_SERVICE_FACTORY_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+#include "components/keyed_service/core/keyed_service_factory.h"
+
+class BrowserStateDependencyManager;
+class KeyedService;
+
+namespace web {
+class BrowserState;
+}
+
+// Base class for Factories that take a BrowserState 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 which services are depended on.
+class KEYED_SERVICE_EXPORT BrowserStateKeyedServiceFactory
+ : public KeyedServiceFactory {
+ public:
+ // A function that supplies the instance of a KeyedService for a given
+ // BrowserState. This is used primarily for testing, where we want to feed
+ // a specific mock into the BSKSF system.
+ typedef scoped_ptr<KeyedService>(*TestingFactoryFunction)(
+ web::BrowserState* context);
+
+ // Associates |factory| with |context| so that |factory| is used to create
+ // the KeyedService when requested. |factory| can be NULL to signal that
+ // KeyedService should be NULL. Multiple calls to SetTestingFactory() are
+ // allowed; previous services will be shut down.
+ void SetTestingFactory(web::BrowserState* context,
+ TestingFactoryFunction factory);
+
+ // Associates |factory| with |context| and immediately returns the created
+ // KeyedService. Since the factory will be used immediately, it may not be
+ // NULL.
+ KeyedService* SetTestingFactoryAndUse(web::BrowserState* context,
+ TestingFactoryFunction factory);
+
+ protected:
+ // BrowserStateKeyedServiceFactories must communicate with a
+ // BrowserStateDependencyManager. For all non-test code, write your subclass
+ // constructors like this:
+ //
+ // MyServiceFactory::MyServiceFactory()
+ // : BrowserStateKeyedServiceFactory(
+ // "MyService",
+ // BrowserStateDependencyManager::GetInstance()) {
+ // }
+ BrowserStateKeyedServiceFactory(const char* name,
+ /*BrowserState*/DependencyManager* manager);
+ ~BrowserStateKeyedServiceFactory() override;
+
+ // Common implementation that maps |context| to some service object. Deals
+ // with incognito and testing contexts per subclass instructions. If |create|
+ // is true, the service will be created using BuildServiceInstanceFor() if it
+ // doesn't already exist.
+ KeyedService* GetServiceForBrowserState(web::BrowserState* context,
+ bool create);
+
+ // Interface for people building a concrete FooServiceFactory: --------------
+
+ // Finds which browser state (if any) to use.
+ virtual web::BrowserState* GetBrowserStateToUse(
+ web::BrowserState* context) const;
+
+ // By default, we create instances of a service lazily and wait until
+ // GetForBrowserState() is called on our subclass. Some services need to be
+ // created as soon as the BrowserState has been brought up.
+ virtual bool ServiceIsCreatedWithBrowserState() const;
+
+ // By default, TestingBrowserStates will be treated like normal contexts.
+ // You can override this so that by default, the service associated with the
+ // TestingBrowserState is NULL. (This is just a shortcut around
+ // SetTestingFactory() to make sure our contexts don't directly refer to the
+ // services they use.)
+ bool ServiceIsNULLWhileTesting() const override;
+
+ // Interface for people building a type of BrowserStateKeyedFactory: -------
+
+ // All subclasses of BrowserStateKeyedServiceFactory must return a
+ // KeyedService instead of just a BrowserStateKeyedBase.
+ virtual scoped_ptr<KeyedService> BuildServiceInstanceFor(
+ web::BrowserState* context) const = 0;
+
+ // A helper object actually listens for notifications about BrowserState
+ // destruction, calculates the order in which things are destroyed and then
+ // does a two pass shutdown.
+ //
+ // First, BrowserStateShutdown() 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, BrowserStateDestroyed() is called on every ServiceFactory
+ // and the default implementation removes it from |mapping_| and deletes
+ // the pointer.
+ virtual void BrowserStateShutdown(web::BrowserState* context);
+ 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.
+ virtual void RegisterBrowserStatePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {}
+
+ // KeyedServiceFactory:
+ scoped_ptr<KeyedService> BuildServiceInstanceFor(
+ base::SupportsUserData* context) const final;
+ bool IsOffTheRecord(base::SupportsUserData* context) const final;
+
+ // KeyedServiceBaseFactory:
+#if defined(OS_IOS)
+ base::SupportsUserData* GetTypedContext(
+ base::SupportsUserData* context) const override;
+ base::SupportsUserData* GetContextForDependencyManager(
+ base::SupportsUserData* context) const override;
+#endif // defined(OS_IOS)
+ base::SupportsUserData* GetContextToUse(
+ base::SupportsUserData* context) const final;
+ bool ServiceIsCreatedWithContext() const final;
+ void ContextShutdown(base::SupportsUserData* context) final;
+ void ContextDestroyed(base::SupportsUserData* context) final;
+ void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserStateKeyedServiceFactory);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_IOS_BROWSER_STATE_KEYED_SERVICE_FACTORY_H_
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
new file mode 100644
index 00000000000..3de6b2f8e21
--- /dev/null
+++ b/chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.cc
@@ -0,0 +1,151 @@
+// 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/keyed_service/ios/refcounted_browser_state_keyed_service_factory.h"
+
+#include "base/logging.h"
+#include "components/keyed_service/core/refcounted_keyed_service.h"
+#include "components/keyed_service/ios/browser_state_context_converter.h"
+#include "components/keyed_service/ios/browser_state_dependency_manager.h"
+#include "ios/web/public/browser_state.h"
+
+void RefcountedBrowserStateKeyedServiceFactory::SetTestingFactory(
+ web::BrowserState* context,
+ TestingFactoryFunction testing_factory) {
+ RefcountedKeyedServiceFactory::SetTestingFactory(
+ context,
+ reinterpret_cast<RefcountedKeyedServiceFactory::TestingFactoryFunction>(
+ testing_factory));
+}
+
+scoped_refptr<RefcountedKeyedService>
+RefcountedBrowserStateKeyedServiceFactory::SetTestingFactoryAndUse(
+ web::BrowserState* context,
+ TestingFactoryFunction testing_factory) {
+ return RefcountedKeyedServiceFactory::SetTestingFactoryAndUse(
+ context,
+ reinterpret_cast<RefcountedKeyedServiceFactory::TestingFactoryFunction>(
+ testing_factory));
+}
+
+RefcountedBrowserStateKeyedServiceFactory::
+ RefcountedBrowserStateKeyedServiceFactory(
+ const char* name,
+ /*BrowserState*/DependencyManager* manager)
+ : RefcountedKeyedServiceFactory(name, manager) {
+}
+
+RefcountedBrowserStateKeyedServiceFactory::
+ ~RefcountedBrowserStateKeyedServiceFactory() {
+}
+
+scoped_refptr<RefcountedKeyedService>
+RefcountedBrowserStateKeyedServiceFactory::GetServiceForBrowserState(
+ web::BrowserState* context,
+ bool create) {
+ return RefcountedKeyedServiceFactory::GetServiceForContext(context, create);
+}
+
+web::BrowserState*
+RefcountedBrowserStateKeyedServiceFactory::GetBrowserStateToUse(
+ web::BrowserState* context) const {
+ DCHECK(CalledOnValidThread());
+
+#ifndef NDEBUG
+ AssertContextWasntDestroyed(context);
+#endif
+
+ // Safe default for Incognito mode: no service.
+ if (context->IsOffTheRecord())
+ return nullptr;
+
+ return context;
+}
+
+bool RefcountedBrowserStateKeyedServiceFactory::
+ ServiceIsCreatedWithBrowserState() const {
+ return KeyedServiceBaseFactory::ServiceIsCreatedWithContext();
+}
+
+bool RefcountedBrowserStateKeyedServiceFactory::ServiceIsNULLWhileTesting()
+ const {
+ return KeyedServiceBaseFactory::ServiceIsNULLWhileTesting();
+}
+
+void RefcountedBrowserStateKeyedServiceFactory::BrowserStateShutdown(
+ web::BrowserState* context) {
+ RefcountedKeyedServiceFactory::ContextShutdown(context);
+}
+
+void RefcountedBrowserStateKeyedServiceFactory::BrowserStateDestroyed(
+ web::BrowserState* context) {
+ RefcountedKeyedServiceFactory::ContextDestroyed(context);
+}
+
+scoped_refptr<RefcountedKeyedService>
+RefcountedBrowserStateKeyedServiceFactory::BuildServiceInstanceFor(
+ base::SupportsUserData* context) const {
+ return BuildServiceInstanceFor(static_cast<web::BrowserState*>(context));
+}
+
+bool RefcountedBrowserStateKeyedServiceFactory::IsOffTheRecord(
+ base::SupportsUserData* context) const {
+ return static_cast<web::BrowserState*>(context)->IsOffTheRecord();
+}
+
+#if defined(OS_IOS)
+base::SupportsUserData*
+RefcountedBrowserStateKeyedServiceFactory::GetTypedContext(
+ base::SupportsUserData* context) const {
+ if (context) {
+ BrowserStateContextConverter* context_converter =
+ BrowserStateContextConverter::GetInstance();
+ if (context_converter) {
+ context = context_converter->GetBrowserStateForContext(context);
+ DCHECK(context);
+ }
+ }
+ return context;
+}
+
+base::SupportsUserData*
+RefcountedBrowserStateKeyedServiceFactory::GetContextForDependencyManager(
+ base::SupportsUserData* context) const {
+ if (context) {
+ BrowserStateContextConverter* context_converter =
+ BrowserStateContextConverter::GetInstance();
+ if (context_converter) {
+ context = context_converter->GetBrowserContextForContext(context);
+ DCHECK(context);
+ }
+ }
+ return context;
+}
+#endif // defined(OS_IOS)
+
+base::SupportsUserData*
+RefcountedBrowserStateKeyedServiceFactory::GetContextToUse(
+ base::SupportsUserData* context) const {
+ return GetBrowserStateToUse(static_cast<web::BrowserState*>(context));
+}
+
+bool RefcountedBrowserStateKeyedServiceFactory::ServiceIsCreatedWithContext()
+ const {
+ return ServiceIsCreatedWithBrowserState();
+}
+
+void RefcountedBrowserStateKeyedServiceFactory::ContextShutdown(
+ base::SupportsUserData* context) {
+ BrowserStateShutdown(static_cast<web::BrowserState*>(context));
+}
+
+void RefcountedBrowserStateKeyedServiceFactory::ContextDestroyed(
+ base::SupportsUserData* context) {
+ BrowserStateDestroyed(static_cast<web::BrowserState*>(context));
+}
+
+void RefcountedBrowserStateKeyedServiceFactory::RegisterPrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ RegisterBrowserStatePrefs(registry);
+}
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
new file mode 100644
index 00000000000..e5fe8477ef1
--- /dev/null
+++ b/chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.h
@@ -0,0 +1,145 @@
+// 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_KEYED_SERVICE_IOS_REFCOUNTED_BROWSER_STATE_KEYED_SERVICE_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_IOS_REFCOUNTED_BROWSER_STATE_KEYED_SERVICE_FACTORY_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+#include "components/keyed_service/core/refcounted_keyed_service_factory.h"
+
+class BrowserStateDependencyManager;
+class RefcountedKeyedService;
+
+namespace web {
+class BrowserState;
+}
+
+// A specialized BrowserStateKeyedServiceFactory that manages a
+// RefcountedThreadSafe<>.
+//
+// While the factory returns RefcountedThreadSafe<>s, the factory itself is a
+// base::NotThreadSafe. Only call methods on this object on the UI thread.
+//
+// Implementers of RefcountedKeyedService should note that we guarantee that
+// ShutdownOnUIThread() is called on the UI thread, but actual object
+// destruction can happen anywhere.
+class KEYED_SERVICE_EXPORT RefcountedBrowserStateKeyedServiceFactory
+ : public RefcountedKeyedServiceFactory {
+ public:
+ // A function that supplies the instance of a KeyedService for a given
+ // BrowserState. This is used primarily for testing, where we want to feed
+ // a specific mock into the BSKSF system.
+ typedef scoped_refptr<RefcountedKeyedService>(*TestingFactoryFunction)(
+ web::BrowserState* context);
+
+ // Associates |factory| with |context| so that |factory| is used to create
+ // the KeyedService when requested. |factory| can be NULL to signal that
+ // KeyedService should be NULL. Multiple calls to SetTestingFactory() are
+ // allowed; previous services will be shut down.
+ void SetTestingFactory(web::BrowserState* context,
+ TestingFactoryFunction factory);
+
+ // Associates |factory| with |context| and immediately returns the created
+ // KeyedService. Since the factory will be used immediately, it may not be
+ // NULL.
+ scoped_refptr<RefcountedKeyedService> SetTestingFactoryAndUse(
+ web::BrowserState* context,
+ TestingFactoryFunction factory);
+
+ protected:
+ // RefcountedBrowserStateKeyedServiceFactories must communicate with a
+ // BrowserStateDependencyManager. For all non-test code, write your subclass
+ // constructors like this:
+ //
+ // MyServiceFactory::MyServiceFactory()
+ // : RefcountedBrowserStateKeyedServiceFactory(
+ // "MyService",
+ // BrowserStateDependencyManager::GetInstance()) {
+ // }
+ RefcountedBrowserStateKeyedServiceFactory(
+ const char* name,
+ /*BrowserState*/DependencyManager* manager);
+ ~RefcountedBrowserStateKeyedServiceFactory() override;
+
+ // Common implementation that maps |context| to some service object. Deals
+ // with incognito and testing contexts per subclass instructions. If |create|
+ // is true, the service will be created using BuildServiceInstanceFor() if it
+ // doesn't already exist.
+ scoped_refptr<RefcountedKeyedService> GetServiceForBrowserState(
+ web::BrowserState* context,
+ bool create);
+
+ // Interface for people building a concrete FooServiceFactory: --------------
+
+ // Finds which browser state (if any) to use.
+ virtual web::BrowserState* GetBrowserStateToUse(
+ web::BrowserState* context) const;
+
+ // By default, we create instances of a service lazily and wait until
+ // GetForBrowserState() is called on our subclass. Some services need to be
+ // created as soon as the BrowserState has been brought up.
+ virtual bool ServiceIsCreatedWithBrowserState() const;
+
+ // By default, TestingBrowserStates will be treated like normal contexts.
+ // You can override this so that by default, the service associated with the
+ // TestingBrowserState is NULL. (This is just a shortcut around
+ // SetTestingFactory() to make sure our contexts don't directly refer to the
+ // services they use.)
+ bool ServiceIsNULLWhileTesting() const override;
+
+ // Interface for people building a type of BrowserStateKeyedFactory: -------
+
+ // All subclasses of BrowserStateKeyedServiceFactory must return a
+ // KeyedService instead of just a BrowserStateKeyedBase.
+ virtual scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
+ web::BrowserState* context) const = 0;
+
+ // A helper object actually listens for notifications about BrowserState
+ // destruction, calculates the order in which things are destroyed and then
+ // does a two pass shutdown.
+ //
+ // First, BrowserStateShutdown() 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, BrowserStateDestroyed() is called on every ServiceFactory
+ // and the default implementation removes it from |mapping_| and deletes
+ // the pointer.
+ virtual void BrowserStateShutdown(web::BrowserState* context);
+ 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.
+ virtual void RegisterBrowserStatePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {}
+
+ // RefcountedKeyedServiceFactory:
+ scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
+ base::SupportsUserData* context) const final;
+ bool IsOffTheRecord(base::SupportsUserData* context) const final;
+
+ // KeyedServiceBaseFactory:
+#if defined(OS_IOS)
+ base::SupportsUserData* GetTypedContext(
+ base::SupportsUserData* context) const override;
+ base::SupportsUserData* GetContextForDependencyManager(
+ base::SupportsUserData* context) const override;
+#endif // defined(OS_IOS)
+ base::SupportsUserData* GetContextToUse(
+ base::SupportsUserData* context) const final;
+ bool ServiceIsCreatedWithContext() const final;
+ void ContextShutdown(base::SupportsUserData* context) final;
+ void ContextDestroyed(base::SupportsUserData* context) final;
+ void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
+
+ DISALLOW_COPY_AND_ASSIGN(RefcountedBrowserStateKeyedServiceFactory);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_IOS_REFCOUNTED_BROWSER_STATE_KEYED_SERVICE_FACTORY_H_
diff --git a/chromium/components/memory_pressure.gypi b/chromium/components/memory_pressure.gypi
new file mode 100644
index 00000000000..8e1e9adba79
--- /dev/null
+++ b/chromium/components/memory_pressure.gypi
@@ -0,0 +1,31 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/memory_pressure
+ 'target_name': 'memory_pressure',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ '../base/base.gyp:base',
+ ],
+ 'sources': [
+ 'memory_pressure/direct_memory_pressure_calculator.cc',
+ 'memory_pressure/direct_memory_pressure_calculator.h',
+ 'memory_pressure/direct_memory_pressure_calculator_win.cc',
+ 'memory_pressure/filtered_memory_pressure_calculator.cc',
+ 'memory_pressure/filtered_memory_pressure_calculator.h',
+ 'memory_pressure/memory_pressure_calculator.h',
+ 'memory_pressure/memory_pressure_listener.cc',
+ 'memory_pressure/memory_pressure_listener.h',
+ 'memory_pressure/memory_pressure_stats_collector.cc',
+ 'memory_pressure/memory_pressure_stats_collector.h',
+ ],
+ },
+ ],
+}
diff --git a/chromium/components/message_port.gypi b/chromium/components/message_port.gypi
index 498405e258f..7891058eeee 100644
--- a/chromium/components/message_port.gypi
+++ b/chromium/components/message_port.gypi
@@ -9,7 +9,7 @@
'type': 'static_library',
'dependencies': [
'../base/base.gyp:base',
- '../mojo/mojo_base.gyp:mojo_common_lib',
+ '../mojo/mojo_base.gyp:mojo_message_pump_lib',
'../third_party/WebKit/public/blink.gyp:blink',
'../third_party/mojo/mojo_public.gyp:mojo_system_cpp_headers',
],
diff --git a/chromium/components/metrics.gypi b/chromium/components/metrics.gypi
index e2e1c49b701..5910f74b3c3 100644
--- a/chromium/components/metrics.gypi
+++ b/chromium/components/metrics.gypi
@@ -15,8 +15,8 @@
'../base/base.gyp:base',
'../base/base.gyp:base_i18n',
'../base/base.gyp:base_prefs',
- '../third_party/zlib/zlib.gyp:zlib',
'component_metrics_proto',
+ 'compression',
'variations',
],
'export_dependent_settings': [
@@ -31,10 +31,15 @@
'metrics/client_info.h',
'metrics/cloned_install_detector.cc',
'metrics/cloned_install_detector.h',
- 'metrics/compression_utils.cc',
- 'metrics/compression_utils.h',
'metrics/daily_event.cc',
'metrics/daily_event.h',
+ 'metrics/drive_metrics_provider.cc',
+ 'metrics/drive_metrics_provider.h',
+ 'metrics/drive_metrics_provider_android.cc',
+ 'metrics/drive_metrics_provider_ios.mm',
+ 'metrics/drive_metrics_provider_linux.cc',
+ 'metrics/drive_metrics_provider_mac.mm',
+ 'metrics/drive_metrics_provider_win.cc',
'metrics/histogram_encoder.cc',
'metrics/histogram_encoder.h',
'metrics/machine_id_provider.h',
@@ -66,6 +71,11 @@
'metrics/metrics_switches.h',
'metrics/persisted_logs.cc',
'metrics/persisted_logs.h',
+ 'metrics/stability_metrics_helper.cc',
+ 'metrics/stability_metrics_helper.h',
+ 'metrics/system_memory_stats_recorder.h',
+ 'metrics/system_memory_stats_recorder_linux.cc',
+ 'metrics/system_memory_stats_recorder_win.cc',
'metrics/url_constants.cc',
'metrics/url_constants.h',
],
@@ -83,25 +93,6 @@
],
},
{
- # GN version: //components/metrics:gpu
- 'target_name': 'metrics_gpu',
- 'type': 'static_library',
- 'include_dirs': [
- '..',
- ],
- 'dependencies': [
- '../base/base.gyp:base',
- '../content/content.gyp:content_browser',
- '../ui/gfx/gfx.gyp:gfx',
- 'component_metrics_proto',
- 'metrics',
- ],
- 'sources': [
- 'metrics/gpu/gpu_metrics_provider.cc',
- 'metrics/gpu/gpu_metrics_provider.h',
- ],
- },
- {
# GN version: //components/metrics:net
'target_name': 'metrics_net',
'type': 'static_library',
@@ -113,13 +104,17 @@
'../net/net.gyp:net',
'../url/url.gyp:url_lib',
'component_metrics_proto',
+ 'data_use_measurement_core',
'metrics',
+ 'version_info',
],
'sources': [
'metrics/net/net_metrics_log_uploader.cc',
'metrics/net/net_metrics_log_uploader.h',
'metrics/net/network_metrics_provider.cc',
'metrics/net/network_metrics_provider.h',
+ 'metrics/net/version_utils.cc',
+ 'metrics/net/version_utils.h',
'metrics/net/wifi_access_point_info_provider.cc',
'metrics/net/wifi_access_point_info_provider.h',
'metrics/net/wifi_access_point_info_provider_chromeos.cc',
@@ -127,32 +122,6 @@
],
},
{
- # GN version: //components/metrics:profiler
- 'target_name': 'metrics_profiler',
- 'type': 'static_library',
- 'include_dirs': [
- '..',
- ],
- 'dependencies': [
- '../content/content.gyp:content_browser',
- '../content/content.gyp:content_common',
- 'component_metrics_proto',
- 'metrics',
- 'variations',
- ],
- 'export_dependent_settings': [
- 'component_metrics_proto',
- ],
- 'sources': [
- 'metrics/profiler/profiler_metrics_provider.cc',
- 'metrics/profiler/profiler_metrics_provider.h',
- 'metrics/profiler/tracking_synchronizer.cc',
- 'metrics/profiler/tracking_synchronizer.h',
- 'metrics/profiler/tracking_synchronizer_observer.cc',
- 'metrics/profiler/tracking_synchronizer_observer.h',
- ],
- },
- {
# Protobuf compiler / generator for UMA (User Metrics Analysis).
#
# GN version: //components/metrics/proto:proto
@@ -220,5 +189,54 @@
},
],
}],
+ ['OS!="ios"', {
+ 'targets': [
+ {
+ # GN version: //components/metrics:gpu
+ 'target_name': 'metrics_gpu',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../content/content.gyp:content_browser',
+ '../ui/gfx/gfx.gyp:gfx',
+ 'component_metrics_proto',
+ 'metrics',
+ ],
+ 'sources': [
+ 'metrics/gpu/gpu_metrics_provider.cc',
+ 'metrics/gpu/gpu_metrics_provider.h',
+ ],
+ },
+ {
+ # GN version: //components/metrics:profiler
+ 'target_name': 'metrics_profiler',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ '../content/content.gyp:content_browser',
+ '../content/content.gyp:content_common',
+ 'component_metrics_proto',
+ 'metrics',
+ 'variations',
+ ],
+ 'export_dependent_settings': [
+ 'component_metrics_proto',
+ ],
+ 'sources': [
+ 'metrics/profiler/profiler_metrics_provider.cc',
+ 'metrics/profiler/profiler_metrics_provider.h',
+ 'metrics/profiler/tracking_synchronizer.cc',
+ 'metrics/profiler/tracking_synchronizer.h',
+ 'metrics/profiler/tracking_synchronizer_observer.cc',
+ 'metrics/profiler/tracking_synchronizer_observer.h',
+ ],
+ },
+ ],
+ }]
],
}
diff --git a/chromium/components/mime_util/mime_util.cc b/chromium/components/mime_util/mime_util.cc
index 3841fbbb690..fa7471bc4be 100644
--- a/chromium/components/mime_util/mime_util.cc
+++ b/chromium/components/mime_util/mime_util.cc
@@ -151,25 +151,25 @@ MimeUtil::MimeUtil() {
}
bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const {
- return image_types_.find(base::StringToLowerASCII(mime_type)) !=
- image_types_.end();
+ return image_types_.find(base::ToLowerASCII(mime_type)) != image_types_.end();
}
bool MimeUtil::IsSupportedNonImageMimeType(const std::string& mime_type) const {
- return non_image_types_.find(base::StringToLowerASCII(mime_type)) !=
+ return non_image_types_.find(base::ToLowerASCII(mime_type)) !=
non_image_types_.end() ||
#if !defined(OS_IOS)
media::IsSupportedMediaMimeType(mime_type) ||
#endif
- (base::StartsWithASCII(mime_type, "text/",
- false /* case insensitive */) &&
+ (base::StartsWith(mime_type, "text/",
+ base::CompareCase::INSENSITIVE_ASCII) &&
!IsUnsupportedTextMimeType(mime_type)) ||
- (base::StartsWithASCII(mime_type, "application/", false) &&
+ (base::StartsWith(mime_type, "application/",
+ base::CompareCase::INSENSITIVE_ASCII) &&
net::MatchesMimeType("application/*+json", mime_type));
}
bool MimeUtil::IsUnsupportedTextMimeType(const std::string& mime_type) const {
- return unsupported_text_types_.find(base::StringToLowerASCII(mime_type)) !=
+ return unsupported_text_types_.find(base::ToLowerASCII(mime_type)) !=
unsupported_text_types_.end();
}
@@ -179,7 +179,8 @@ bool MimeUtil::IsSupportedJavascriptMimeType(
}
bool MimeUtil::IsSupportedMimeType(const std::string& mime_type) const {
- return (base::StartsWithASCII(mime_type, "image/", false) &&
+ return (base::StartsWith(mime_type, "image/",
+ base::CompareCase::INSENSITIVE_ASCII) &&
IsSupportedImageMimeType(mime_type)) ||
IsSupportedNonImageMimeType(mime_type);
}
@@ -221,8 +222,8 @@ net::CertificateMimeType GetCertificateMimeTypeForMimeType(
// Don't create a map, there is only one entry in the table,
// except on Android.
for (size_t i = 0; i < arraysize(kSupportedCertificateTypes); ++i) {
- if (base::strcasecmp(mime_type.c_str(),
- kSupportedCertificateTypes[i].mime_type) == 0) {
+ if (base::EqualsCaseInsensitiveASCII(
+ mime_type, kSupportedCertificateTypes[i].mime_type)) {
return kSupportedCertificateTypes[i].cert_type;
}
}
diff --git a/chromium/components/nacl.gyp b/chromium/components/nacl.gyp
index a133cdafcda..30ee7437dc8 100644
--- a/chromium/components/nacl.gyp
+++ b/chromium/components/nacl.gyp
@@ -119,6 +119,7 @@
'dependencies': [
'nacl_common',
'nacl_switches',
+ 'url_formatter/url_formatter.gyp:url_formatter',
'../native_client/src/trusted/service_runtime/service_runtime.gyp:sel',
'../content/content.gyp:content_browser',
],
@@ -174,7 +175,6 @@
'nacl_common',
'../content/content.gyp:content_renderer',
'../components/nacl/renderer/plugin/plugin.gyp:nacl_trusted_plugin',
- '../third_party/jsoncpp/jsoncpp.gyp:jsoncpp',
'../third_party/WebKit/public/blink.gyp:blink',
],
},
@@ -292,7 +292,6 @@
'nacl_switches',
'../components/tracing.gyp:tracing',
'../crypto/crypto.gyp:crypto',
- '../sandbox/sandbox.gyp:libc_urandom_override',
'../sandbox/sandbox.gyp:sandbox',
'../ppapi/ppapi_internal.gyp:ppapi_proxy',
],
diff --git a/chromium/components/nacl_helper_nonsfi_unittests.isolate b/chromium/components/nacl_helper_nonsfi_unittests.isolate
index b7973b9b052..f0e05a26a56 100644
--- a/chromium/components/nacl_helper_nonsfi_unittests.isolate
+++ b/chromium/components/nacl_helper_nonsfi_unittests.isolate
@@ -12,7 +12,6 @@
'<(PRODUCT_DIR)/nacl_helper_nonsfi_unittests',
'<(PRODUCT_DIR)/nacl_helper_nonsfi_unittests_main',
],
- 'read_only': 1,
},
}],
],
diff --git a/chromium/components/nacl_loader_unittests.isolate b/chromium/components/nacl_loader_unittests.isolate
index 501d185d2dd..4a6fe8c1310 100644
--- a/chromium/components/nacl_loader_unittests.isolate
+++ b/chromium/components/nacl_loader_unittests.isolate
@@ -8,10 +8,6 @@
'command': [
'<(PRODUCT_DIR)/nacl_loader_unittests<(EXECUTABLE_SUFFIX)',
],
- 'files': [
- '<(PRODUCT_DIR)/nacl_loader_unittests<(EXECUTABLE_SUFFIX)',
- ],
- 'read_only': 1,
},
}],
],
diff --git a/chromium/components/nacl_nonsfi.gyp b/chromium/components/nacl_nonsfi.gyp
index 8ae540fde93..f44fa761345 100644
--- a/chromium/components/nacl_nonsfi.gyp
+++ b/chromium/components/nacl_nonsfi.gyp
@@ -71,7 +71,6 @@
'-lgles2_utils_nacl',
'-lgpu_ipc_nacl',
'-lipc_nacl_nonsfi',
- '-llatency_info_nacl',
'-lnacl_helper_nonsfi_sandbox',
'-lplatform',
'-lppapi_ipc_nacl',
@@ -97,7 +96,6 @@
'>(tc_lib_dir_nonsfi_helper32)/libgles2_utils_nacl.a',
'>(tc_lib_dir_nonsfi_helper32)/libgpu_ipc_nacl.a',
'>(tc_lib_dir_nonsfi_helper32)/libipc_nacl_nonsfi.a',
- '>(tc_lib_dir_nonsfi_helper32)/liblatency_info_nacl.a',
'>(tc_lib_dir_nonsfi_helper32)/libnacl_helper_nonsfi_sandbox.a',
'>(tc_lib_dir_nonsfi_helper32)/libplatform.a',
'>(tc_lib_dir_nonsfi_helper32)/libppapi_ipc_nacl.a',
@@ -122,7 +120,6 @@
'>(tc_lib_dir_nonsfi_helper_arm)/libgles2_utils_nacl.a',
'>(tc_lib_dir_nonsfi_helper_arm)/libgpu_ipc_nacl.a',
'>(tc_lib_dir_nonsfi_helper_arm)/libipc_nacl_nonsfi.a',
- '>(tc_lib_dir_nonsfi_helper_arm)/liblatency_info_nacl.a',
'>(tc_lib_dir_nonsfi_helper_arm)/libnacl_helper_nonsfi_sandbox.a',
'>(tc_lib_dir_nonsfi_helper_arm)/libplatform.a',
'>(tc_lib_dir_nonsfi_helper_arm)/libppapi_ipc_nacl.a',
diff --git a/chromium/components/navigation_interception.gypi b/chromium/components/navigation_interception.gypi
index 35112010a03..7ccc4cd80d6 100644
--- a/chromium/components/navigation_interception.gypi
+++ b/chromium/components/navigation_interception.gypi
@@ -23,8 +23,8 @@
],
'sources': [
# Note: sources list duplicated in GN build.
- 'navigation_interception/intercept_navigation_resource_throttle.cc',
- 'navigation_interception/intercept_navigation_resource_throttle.h',
+ 'navigation_interception/intercept_navigation_throttle.cc',
+ 'navigation_interception/intercept_navigation_throttle.h',
'navigation_interception/navigation_params.cc',
'navigation_interception/navigation_params.h',
],
diff --git a/chromium/components/net_log.gypi b/chromium/components/net_log.gypi
new file mode 100644
index 00000000000..b99ad3ebb42
--- /dev/null
+++ b/chromium/components/net_log.gypi
@@ -0,0 +1,31 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/net_log
+ 'target_name': 'net_log',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../net/net.gyp:net',
+ 'data_reduction_proxy_core_common',
+ 'version_info',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'net_log/chrome_net_log.cc',
+ 'net_log/chrome_net_log.h',
+ 'net_log/net_export_ui_constants.cc',
+ 'net_log/net_export_ui_constants.h',
+ 'net_log/net_log_temp_file.cc',
+ 'net_log/net_log_temp_file.h',
+ ],
+ },
+ ],
+}
diff --git a/chromium/components/offline_pages.gypi b/chromium/components/offline_pages.gypi
index 668c8062dc5..322f676b0d8 100644
--- a/chromium/components/offline_pages.gypi
+++ b/chromium/components/offline_pages.gypi
@@ -15,17 +15,53 @@
'../base/base.gyp:base',
'../net/net.gyp:net',
'../url/url.gyp:url_lib',
+ '../third_party/leveldatabase/leveldatabase.gyp:leveldatabase',
+ 'components.gyp:leveldb_proto',
'keyed_service_core',
+ 'offline_pages_proto',
],
'sources': [
'offline_pages/offline_page_archiver.h',
+ 'offline_pages/offline_page_feature.cc',
+ 'offline_pages/offline_page_feature.h',
'offline_pages/offline_page_item.cc',
'offline_pages/offline_page_item.h',
'offline_pages/offline_page_model.cc',
'offline_pages/offline_page_model.h',
'offline_pages/offline_page_metadata_store.cc',
'offline_pages/offline_page_metadata_store.h',
+ 'offline_pages/offline_page_metadata_store_impl.cc',
+ 'offline_pages/offline_page_metadata_store_impl.h',
+ 'offline_pages/offline_page_switches.cc',
+ 'offline_pages/offline_page_switches.h',
],
},
+ {
+ # Protobuf compiler / generator for the offline page item protocol buffer.
+ # GN version: //components/offline_pages/proto
+ 'target_name': 'offline_pages_proto',
+ 'type': 'static_library',
+ 'sources': [ 'offline_pages/proto/offline_pages.proto', ],
+ 'variables': {
+ 'proto_in_dir': 'offline_pages/proto',
+ 'proto_out_dir': 'components/offline_pages/proto',
+ },
+ 'includes': [ '../build/protoc.gypi', ],
+ },
+ ],
+ 'conditions': [
+ ['OS == "android"', {
+ 'targets': [
+ {
+ # GN: //components/offline_pages:offline_pages_enums_java
+ 'target_name': 'offline_pages_enums_java',
+ 'type': 'none',
+ 'variables': {
+ 'source_file': 'offline_pages/offline_page_model.h',
+ },
+ 'includes': [ '../build/android/java_cpp_enum.gypi' ],
+ },
+ ],
+ }],
],
}
diff --git a/chromium/components/omnibox.gypi b/chromium/components/omnibox.gypi
index c8fe51e9a2b..0dfb932bb38 100644
--- a/chromium/components/omnibox.gypi
+++ b/chromium/components/omnibox.gypi
@@ -12,22 +12,30 @@
'../base/base.gyp:base',
'../base/base.gyp:base_i18n',
'../net/net.gyp:net',
+ '../skia/skia.gyp:skia',
'../sql/sql.gyp:sql',
'../third_party/protobuf/protobuf.gyp:protobuf_lite',
'../ui/base/ui_base.gyp:ui_base',
+ '../ui/gfx/gfx.gyp:gfx',
'../url/url.gyp:url_lib',
'bookmarks_browser',
+ 'crash_core_common', # TODO(mpearson): remove once 464926 is fixed.
+ 'metrics',
'component_metrics_proto',
'components_resources.gyp:components_resources',
'components_strings.gyp:components_strings',
+ 'data_use_measurement_core',
'history_core_browser',
'keyed_service_core',
+ 'omnibox_common',
'omnibox_in_memory_url_index_cache_proto',
+ 'open_from_clipboard',
'pref_registry',
'query_parser',
'search',
'search_engines',
- 'url_fixer',
+ 'toolbar',
+ 'url_formatter/url_formatter.gyp:url_formatter',
'variations_http_provider',
],
'export_dependent_settings': [
@@ -65,6 +73,8 @@
'omnibox/browser/bookmark_provider.h',
'omnibox/browser/builtin_provider.cc',
'omnibox/browser/builtin_provider.h',
+ 'omnibox/browser/clipboard_url_provider.cc',
+ 'omnibox/browser/clipboard_url_provider.h',
'omnibox/browser/history_provider.cc',
'omnibox/browser/history_provider.h',
'omnibox/browser/history_quick_provider.cc',
@@ -79,16 +89,32 @@
'omnibox/browser/keyword_extensions_delegate.h',
'omnibox/browser/keyword_provider.cc',
'omnibox/browser/keyword_provider.h',
+ 'omnibox/browser/omnibox_client.h',
+ 'omnibox/browser/omnibox_controller.cc',
+ 'omnibox/browser/omnibox_controller.h',
+ 'omnibox/browser/omnibox_edit_controller.cc',
+ 'omnibox/browser/omnibox_edit_controller.h',
+ 'omnibox/browser/omnibox_edit_model.cc',
+ 'omnibox/browser/omnibox_edit_model.h',
+ 'omnibox/browser/omnibox_event_global_tracker.cc',
+ 'omnibox/browser/omnibox_event_global_tracker.h',
'omnibox/browser/omnibox_field_trial.cc',
'omnibox/browser/omnibox_field_trial.h',
'omnibox/browser/omnibox_log.cc',
'omnibox/browser/omnibox_log.h',
+ 'omnibox/browser/omnibox_metrics_provider.cc',
+ 'omnibox/browser/omnibox_metrics_provider.h',
+ 'omnibox/browser/omnibox_navigation_observer.h',
+ 'omnibox/browser/omnibox_popup_model.cc',
+ 'omnibox/browser/omnibox_popup_model.h',
'omnibox/browser/omnibox_popup_model_observer.h',
'omnibox/browser/omnibox_popup_view.h',
'omnibox/browser/omnibox_pref_names.cc',
'omnibox/browser/omnibox_pref_names.h',
'omnibox/browser/omnibox_switches.cc',
'omnibox/browser/omnibox_switches.h',
+ 'omnibox/browser/omnibox_view.cc',
+ 'omnibox/browser/omnibox_view.h',
'omnibox/browser/scored_history_match.cc',
'omnibox/browser/scored_history_match.h',
'omnibox/browser/search_provider.cc',
@@ -97,6 +123,8 @@
'omnibox/browser/search_suggestion_parser.h',
'omnibox/browser/shortcuts_backend.cc',
'omnibox/browser/shortcuts_backend.h',
+ 'omnibox/browser/shortcuts_constants.cc',
+ 'omnibox/browser/shortcuts_constants.h',
'omnibox/browser/shortcuts_database.cc',
'omnibox/browser/shortcuts_database.h',
'omnibox/browser/shortcuts_provider.cc',
@@ -107,6 +135,8 @@
'omnibox/browser/url_index_private_data.h',
'omnibox/browser/url_prefix.cc',
'omnibox/browser/url_prefix.h',
+ 'omnibox/browser/verbatim_match.cc',
+ 'omnibox/browser/verbatim_match.h',
'omnibox/browser/zero_suggest_provider.cc',
'omnibox/browser/zero_suggest_provider.h',
],
@@ -120,7 +150,7 @@
],
'sources': [
# Note: sources list duplicated in GN build.
- 'components/omnibox/omnibox_focus_state.h',
+ 'omnibox/common/omnibox_focus_state.h',
],
},
{
diff --git a/chromium/components/omnibox_strings.grdp b/chromium/components/omnibox_strings.grdp
index aaa40eb241b..93b3eb93148 100644
--- a/chromium/components/omnibox_strings.grdp
+++ b/chromium/components/omnibox_strings.grdp
@@ -13,5 +13,7 @@
<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;enter query&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>
</grit-part>
diff --git a/chromium/components/open_from_clipboard.gypi b/chromium/components/open_from_clipboard.gypi
index 27cef25453d..d9901477b4c 100644
--- a/chromium/components/open_from_clipboard.gypi
+++ b/chromium/components/open_from_clipboard.gypi
@@ -5,23 +5,38 @@
{
'targets': [
{
+ # GN version: //components/open_from_clipboard
'target_name': 'open_from_clipboard',
'type': 'static_library',
'dependencies': [
'../base/base.gyp:base',
'../url/url.gyp:url_lib',
- 'components_strings.gyp:components_strings',
- 'omnibox_browser',
],
'include_dirs': [
'..',
],
'sources': [
+ # Note: sources list duplicated in GN build.
+ 'open_from_clipboard/clipboard_recent_content.cc',
'open_from_clipboard/clipboard_recent_content.h',
'open_from_clipboard/clipboard_recent_content_ios.h',
'open_from_clipboard/clipboard_recent_content_ios.mm',
- 'open_from_clipboard/clipboard_url_provider.cc',
- 'open_from_clipboard/clipboard_url_provider.h',
+ ],
+ },
+ {
+ # GN version: //components/open_from_clipboard:test_support
+ 'target_name': 'open_from_clipboard_test_support',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'open_from_clipboard',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'open_from_clipboard/fake_clipboard_recent_content.cc',
+ 'open_from_clipboard/fake_clipboard_recent_content.h',
],
},
],
diff --git a/chromium/components/open_from_clipboard_strings.grdp b/chromium/components/open_from_clipboard_strings.grdp
deleted file mode 100644
index c6ec2b57e80..00000000000
--- a/chromium/components/open_from_clipboard_strings.grdp
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<grit-part>
- <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>
-</grit-part>
diff --git a/chromium/components/page_load_metrics.gypi b/chromium/components/page_load_metrics.gypi
new file mode 100644
index 00000000000..d9e73028196
--- /dev/null
+++ b/chromium/components/page_load_metrics.gypi
@@ -0,0 +1,66 @@
+# 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.
+
+{
+ 'conditions': [
+ ['OS != "ios"', {
+ 'targets': [
+ {
+ 'target_name': 'page_load_metrics_common',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../ipc/ipc.gyp:ipc',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'page_load_metrics/common/page_load_metrics_messages.cc',
+ 'page_load_metrics/common/page_load_metrics_messages.h',
+ 'page_load_metrics/common/page_load_timing.cc',
+ 'page_load_metrics/common/page_load_timing.h',
+ ],
+ },
+ {
+ 'target_name': 'page_load_metrics_browser',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../content/content.gyp:content_browser',
+ '../ipc/ipc.gyp:ipc',
+ 'page_load_metrics_common',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'page_load_metrics/browser/metrics_web_contents_observer.cc',
+ 'page_load_metrics/browser/metrics_web_contents_observer.h',
+ ],
+ },
+ {
+ 'target_name': 'page_load_metrics_renderer',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../content/content.gyp:content_renderer',
+ '../third_party/WebKit/public/blink.gyp:blink',
+ '../url/url.gyp:url_lib',
+ 'page_load_metrics_common',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'page_load_metrics/renderer/metrics_render_frame_observer.cc',
+ 'page_load_metrics/renderer/metrics_render_frame_observer.h',
+ 'page_load_metrics/renderer/page_timing_metrics_sender.cc',
+ 'page_load_metrics/renderer/page_timing_metrics_sender.h',
+ ],
+ },
+ ],
+ }]
+ ]
+}
diff --git a/chromium/components/password_manager.gypi b/chromium/components/password_manager.gypi
index 631095fdb2a..a541d0a63e0 100644
--- a/chromium/components/password_manager.gypi
+++ b/chromium/components/password_manager.gypi
@@ -22,6 +22,7 @@
'../third_party/re2/re2.gyp:re2',
'password_manager_core_common',
'password_manager_core_browser_proto',
+ 'url_formatter/url_formatter.gyp:url_formatter',
],
'include_dirs': [
'..',
@@ -52,6 +53,7 @@
'password_manager/core/browser/credential_manager_pending_request_task.h',
'password_manager/core/browser/credential_manager_pending_require_user_mediation_task.cc',
'password_manager/core/browser/credential_manager_pending_require_user_mediation_task.h',
+ 'password_manager/core/browser/credentials_filter.h',
'password_manager/core/browser/export/csv_writer.cc',
'password_manager/core/browser/export/csv_writer.h',
'password_manager/core/browser/facet_manager.cc',
@@ -81,11 +83,15 @@
'password_manager/core/browser/password_manager.h',
'password_manager/core/browser/password_manager_client.cc',
'password_manager/core/browser/password_manager_client.h',
+ 'password_manager/core/browser/password_manager_constants.cc',
+ 'password_manager/core/browser/password_manager_constants.h',
'password_manager/core/browser/password_manager_driver.h',
'password_manager/core/browser/password_manager_internals_service.cc',
'password_manager/core/browser/password_manager_internals_service.h',
'password_manager/core/browser/password_manager_metrics_util.cc',
'password_manager/core/browser/password_manager_metrics_util.h',
+ 'password_manager/core/browser/password_manager_settings_migration_experiment.cc',
+ 'password_manager/core/browser/password_manager_settings_migration_experiment.h',
'password_manager/core/browser/password_manager_util.cc',
'password_manager/core/browser/password_manager_util.h',
'password_manager/core/browser/password_store.cc',
@@ -191,6 +197,31 @@
'password_manager/core/common/password_manager_ui.h',
],
},
+ {
+ # GN version: //components/password_manager/sync/browser
+ 'target_name': 'password_manager_sync_browser',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../google_apis/google_apis.gyp:google_apis',
+ '../net/net.gyp:net',
+ '../sync/sync.gyp:sync',
+ 'autofill_core_common',
+ 'password_manager_core_browser',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'password_manager/sync/browser/password_model_worker.cc',
+ 'password_manager/sync/browser/password_model_worker.h',
+ 'password_manager/sync/browser/password_sync_util.cc',
+ 'password_manager/sync/browser/password_sync_util.h',
+ 'password_manager/sync/browser/sync_store_result_filter.cc',
+ 'password_manager/sync/browser/sync_store_result_filter.h',
+ ],
+ },
],
'conditions': [
['OS != "ios"', {
@@ -259,6 +290,8 @@
],
'sources': [
# Note: sources list duplicated in GN build.
+ 'password_manager/content/browser/bad_message.cc',
+ 'password_manager/content/browser/bad_message.h',
'password_manager/content/browser/content_password_manager_driver.cc',
'password_manager/content/browser/content_password_manager_driver.h',
'password_manager/content/browser/content_password_manager_driver_factory.cc',
diff --git a/chromium/components/pdf_strings.grdp b/chromium/components/pdf_strings.grdp
index 7a839097d3e..073a85bfdc7 100644
--- a/chromium/components/pdf_strings.grdp
+++ b/chromium/components/pdf_strings.grdp
@@ -4,14 +4,53 @@
<message name="IDS_PDF_NEED_PASSWORD" desc="A message asking the user for a password to open a PDF file.">
This document is password protected. Please enter a password.
</message>
+ <message name="IDS_PDF_PASSWORD_SUBMIT" desc="Button label for the buton to submit the PDF password form">
+ Submit
+ </message>
+ <message name="IDS_PDF_PASSWORD_INVALID" desc="Error message when an invalid password is entered">
+ Incorrect password
+ </message>
+
<message name="IDS_PDF_PAGE_LOADING" desc="A message displayed on the PDF page while page is loading.">
Loading...
</message>
<message name="IDS_PDF_PAGE_LOAD_FAILED" desc="A message displayed on the PDF control to indicate that the PDF document failed to load.">
Failed to load PDF document
</message>
- <message name="IDS_PDF_PROGRESS_LOADING" desc="A message displayed on the progress control over PDF page during document loading.">
- Loading
+ <message name="IDS_PDF_PAGE_RELOAD_BUTTON" desc="Button label for the button to reload a PDF which has failed to load">
+ Reload
+ </message>
+
+ <message name="IDS_PDF_BOOKMARKS" desc="Label for the bookmarks (table of contents) of a PDF document. Used as a heading for the bookmarks menu, and as a tooltip to open that menu">
+ Bookmarks
+ </message>
+
+ <message name="IDS_PDF_TOOLTIP_ROTATE_CW" desc="Button tooltip for the button which rotates a PDF document clockwise">
+ Rotate clockwise
+ </message>
+ <message name="IDS_PDF_TOOLTIP_ROTATE_CCW" desc="Button tooltip for the button which rotates a PDF document counterclockwise">
+ Rotate counterclockwise
+ </message>
+ <message name="IDS_PDF_TOOLTIP_SAVE" desc="Button tooltip for the button to save a PDF document">
+ Save
+ </message>
+ <message name="IDS_PDF_TOOLTIP_PRINT" desc="Button tooltip for the button to print a PDF document">
+ Print
+ </message>
+ <message name="IDS_PDF_TOOLTIP_FIT_PAGE" desc="Button tooltip for the button which zooms a PDF so that a single page is visible on screen">
+ Fit to page
+ </message>
+ <message name="IDS_PDF_TOOLTIP_FIT_WIDTH" desc="Button tooltip for the button which zooms a PDF so that the width of a single page fills the window horizontally">
+ Fit to width
+ </message>
+ <message name="IDS_PDF_TOOLTIP_ZOOM_IN" desc="Button tooltip for the button which zooms in a PDF, so that the document appears larger">
+ Zoom in
+ </message>
+ <message name="IDS_PDF_TOOLTIP_ZOOM_OUT" desc="Button tooltip for the button which zooms out a PDF, so that the document appears smaller">
+ Zoom out
+ </message>
+ <message name="IDS_PDF_LABEL_PAGE_NUMBER" desc="Label for the input field containing the current page number">
+ Page number
</message>
</if>
</grit-part>
diff --git a/chromium/components/policy.gypi b/chromium/components/policy.gypi
index f37d4ce0cd7..d032ace8f37 100644
--- a/chromium/components/policy.gypi
+++ b/chromium/components/policy.gypi
@@ -62,6 +62,11 @@
'includes': [
'policy/policy_browser.gypi',
],
+ 'conditions': [
+ ['OS=="android"', {
+ 'dependencies': ['policy_jni_headers']},
+ ],
+ ],
},
],
}, { # component=="shared_library"
@@ -82,6 +87,11 @@
'dependencies': [
'policy_component',
],
+ 'conditions': [
+ ['OS=="android"', {
+ 'dependencies': ['policy_jni_headers']},
+ ],
+ ],
},
{
# GN version: //components/policy:policy_component_browser
@@ -339,6 +349,23 @@
},
],
}],
+ ['OS=="android"',
+ {
+ 'targets' : [
+ {
+ 'target_name' : 'policy_jni_headers',
+ 'type': 'none',
+ 'sources': [
+ 'policy/android/java/src/org/chromium/policy/CombinedPolicyProvider.java',
+ 'policy/android/java/src/org/chromium/policy/PolicyConverter.java',
+ ],
+ 'variables': {
+ 'jni_gen_package': 'policy',
+ },
+ 'includes': [ '../build/jni_generator.gypi' ],
+ },
+ ],
+ }],
['OS=="android" and configuration_policy==1', {
'targets': [
{
diff --git a/chromium/components/policy/policy_browser.gypi b/chromium/components/policy/policy_browser.gypi
index 701a55f4fde..8f6ddb39a96 100644
--- a/chromium/components/policy/policy_browser.gypi
+++ b/chromium/components/policy/policy_browser.gypi
@@ -46,6 +46,8 @@
'core/browser/autofill_policy_handler.h',
'core/browser/browser_policy_connector.cc',
'core/browser/browser_policy_connector.h',
+ 'core/browser/browser_policy_connector_base.cc',
+ 'core/browser/browser_policy_connector_base.h',
'core/browser/browser_policy_connector_ios.h',
'core/browser/browser_policy_connector_ios.mm',
'core/browser/cloud/message_util.cc',
@@ -61,6 +63,19 @@
'core/browser/url_blacklist_policy_handler.cc',
'core/browser/url_blacklist_policy_handler.h',
],
+ 'conditions': [
+ ['OS=="android"', {
+ 'sources': [
+ 'core/browser/android/android_combined_policy_provider.cc',
+ 'core/browser/android/android_combined_policy_provider.h',
+ 'core/browser/android/component_jni_registrar.cc',
+ 'core/browser/android/component_jni_registrar.h',
+ 'core/browser/android/policy_converter.cc',
+ 'core/browser/android/policy_converter.h',
+ ],
+ 'dependencies': [ 'policy_jni_headers' ]
+ }]
+ ]
}],
],
}
diff --git a/chromium/components/policy/policy_common.gypi b/chromium/components/policy/policy_common.gypi
index a1b570e9659..55573e6596f 100644
--- a/chromium/components/policy/policy_common.gypi
+++ b/chromium/components/policy/policy_common.gypi
@@ -23,6 +23,7 @@
'../third_party/re2/re2.gyp:re2',
'../url/url.gyp:url_lib',
'cloud_policy_proto',
+ 'data_use_measurement_core',
'json_schema',
'policy',
],
@@ -107,9 +108,6 @@
'core/common/policy_namespace.h',
'core/common/policy_pref_names.cc',
'core/common/policy_pref_names.h',
- 'core/common/policy_provider_android.cc',
- 'core/common/policy_provider_android.h',
- 'core/common/policy_provider_android_delegate.h',
'core/common/policy_service.cc',
'core/common/policy_service.h',
'core/common/policy_service_impl.cc',
diff --git a/chromium/components/policy/resources/policy_templates.grd b/chromium/components/policy/resources/policy_templates.grd
new file mode 100644
index 00000000000..803e8696499
--- /dev/null
+++ b/chromium/components/policy/resources/policy_templates.grd
@@ -0,0 +1,309 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- This file contains definitions of resources that are used in policy
+templates and will be translated for each locale. -->
+
+<grit base_dir="." latest_public_release="0" current_release="1"
+ source_lang_id="en" enc_check="möl">
+ <outputs>
+ <output filename="app/policy/common/html/am/chrome_policy_list.html" type="doc" lang="am" />
+ <output filename="app/policy/common/html/ar/chrome_policy_list.html" type="doc" lang="ar" />
+ <output filename="app/policy/common/html/bg/chrome_policy_list.html" type="doc" lang="bg" />
+ <output filename="app/policy/common/html/bn/chrome_policy_list.html" type="doc" lang="bn" />
+ <output filename="app/policy/common/html/ca/chrome_policy_list.html" type="doc" lang="ca" />
+ <output filename="app/policy/common/html/cs/chrome_policy_list.html" type="doc" lang="cs" />
+ <output filename="app/policy/common/html/da/chrome_policy_list.html" type="doc" lang="da" />
+ <output filename="app/policy/common/html/de/chrome_policy_list.html" type="doc" lang="de" />
+ <output filename="app/policy/common/html/el/chrome_policy_list.html" type="doc" lang="el" />
+ <output filename="app/policy/common/html/en-GB/chrome_policy_list.html" type="doc" lang="en-GB" />
+ <output filename="app/policy/common/html/en-US/chrome_policy_list.html" type="doc" lang="en" />
+ <output filename="app/policy/common/html/es/chrome_policy_list.html" type="doc" lang="es" />
+ <output filename="app/policy/common/html/es-419/chrome_policy_list.html" type="doc" lang="es-419" />
+ <output filename="app/policy/common/html/et/chrome_policy_list.html" type="doc" lang="et" />
+ <output filename="app/policy/common/html/fa/chrome_policy_list.html" type="doc" lang="fa" />
+ <output filename="app/policy/common/html/fi/chrome_policy_list.html" type="doc" lang="fi" />
+ <output filename="app/policy/common/html/fil/chrome_policy_list.html" type="doc" lang="fil" />
+ <output filename="app/policy/common/html/fr/chrome_policy_list.html" type="doc" lang="fr" />
+ <output filename="app/policy/common/html/gu/chrome_policy_list.html" type="doc" lang="gu" />
+ <output filename="app/policy/common/html/he/chrome_policy_list.html" type="doc" lang="he" />
+ <output filename="app/policy/common/html/hi/chrome_policy_list.html" type="doc" lang="hi" />
+ <output filename="app/policy/common/html/hr/chrome_policy_list.html" type="doc" lang="hr" />
+ <output filename="app/policy/common/html/hu/chrome_policy_list.html" type="doc" lang="hu" />
+ <output filename="app/policy/common/html/id/chrome_policy_list.html" type="doc" lang="id" />
+ <output filename="app/policy/common/html/it/chrome_policy_list.html" type="doc" lang="it" />
+ <output filename="app/policy/common/html/ja/chrome_policy_list.html" type="doc" lang="ja" />
+ <output filename="app/policy/common/html/kn/chrome_policy_list.html" type="doc" lang="kn" />
+ <output filename="app/policy/common/html/ko/chrome_policy_list.html" type="doc" lang="ko" />
+ <output filename="app/policy/common/html/lt/chrome_policy_list.html" type="doc" lang="lt" />
+ <output filename="app/policy/common/html/lv/chrome_policy_list.html" type="doc" lang="lv" />
+ <output filename="app/policy/common/html/ml/chrome_policy_list.html" type="doc" lang="ml" />
+ <output filename="app/policy/common/html/mr/chrome_policy_list.html" type="doc" lang="mr" />
+ <output filename="app/policy/common/html/ms/chrome_policy_list.html" type="doc" lang="ms" />
+ <output filename="app/policy/common/html/nl/chrome_policy_list.html" type="doc" lang="nl" />
+ <output filename="app/policy/common/html/nb/chrome_policy_list.html" type="doc" lang="no" />
+ <!-- 'no' for Norwegian Bokmål. It should be 'nb'. -->
+ <output filename="app/policy/common/html/pl/chrome_policy_list.html" type="doc" lang="pl" />
+ <output filename="app/policy/common/html/pt-BR/chrome_policy_list.html" type="doc" lang="pt-BR" />
+ <output filename="app/policy/common/html/pt-PT/chrome_policy_list.html" type="doc" lang="pt-PT" />
+ <output filename="app/policy/common/html/ro/chrome_policy_list.html" type="doc" lang="ro" />
+ <output filename="app/policy/common/html/ru/chrome_policy_list.html" type="doc" lang="ru" />
+ <output filename="app/policy/common/html/sk/chrome_policy_list.html" type="doc" lang="sk" />
+ <output filename="app/policy/common/html/sl/chrome_policy_list.html" type="doc" lang="sl" />
+ <output filename="app/policy/common/html/sr/chrome_policy_list.html" type="doc" lang="sr" />
+ <output filename="app/policy/common/html/sv/chrome_policy_list.html" type="doc" lang="sv" />
+ <output filename="app/policy/common/html/sw/chrome_policy_list.html" type="doc" lang="sw" />
+ <output filename="app/policy/common/html/ta/chrome_policy_list.html" type="doc" lang="ta" />
+ <output filename="app/policy/common/html/te/chrome_policy_list.html" type="doc" lang="te" />
+ <output filename="app/policy/common/html/th/chrome_policy_list.html" type="doc" lang="th" />
+ <output filename="app/policy/common/html/tr/chrome_policy_list.html" type="doc" lang="tr" />
+ <output filename="app/policy/common/html/uk/chrome_policy_list.html" type="doc" lang="uk" />
+ <output filename="app/policy/common/html/vi/chrome_policy_list.html" type="doc" lang="vi" />
+ <output filename="app/policy/common/html/zh-CN/chrome_policy_list.html" type="doc" lang="zh-CN" />
+ <output filename="app/policy/common/html/zh-TW/chrome_policy_list.html" type="doc" lang="zh-TW" />
+ <if expr="is_win">
+ <output filename="app/policy/windows/examples/chrome.reg" type="reg" lang="en" />
+ <output filename="app/policy/windows/admx/chrome.admx" type="admx" lang="en" />
+
+ <output filename="app/policy/windows/admx/am/chrome.adml" type="adml" lang="am" />
+ <output filename="app/policy/windows/admx/ar/chrome.adml" type="adml" lang="ar" />
+ <output filename="app/policy/windows/admx/bg/chrome.adml" type="adml" lang="bg" />
+ <output filename="app/policy/windows/admx/bn/chrome.adml" type="adml" lang="bn" />
+ <output filename="app/policy/windows/admx/ca/chrome.adml" type="adml" lang="ca" />
+ <output filename="app/policy/windows/admx/cs/chrome.adml" type="adml" lang="cs" />
+ <output filename="app/policy/windows/admx/da/chrome.adml" type="adml" lang="da" />
+ <output filename="app/policy/windows/admx/de/chrome.adml" type="adml" lang="de" />
+ <output filename="app/policy/windows/admx/el/chrome.adml" type="adml" lang="el" />
+ <output filename="app/policy/windows/admx/en-GB/chrome.adml" type="adml" lang="en-GB" />
+ <output filename="app/policy/windows/admx/en-US/chrome.adml" type="adml" lang="en" />
+ <output filename="app/policy/windows/admx/es/chrome.adml" type="adml" lang="es" />
+ <output filename="app/policy/windows/admx/es-419/chrome.adml" type="adml" lang="es-419" />
+ <output filename="app/policy/windows/admx/et/chrome.adml" type="adml" lang="et" />
+ <output filename="app/policy/windows/admx/fa/chrome.adml" type="adml" lang="fa" />
+ <output filename="app/policy/windows/admx/fi/chrome.adml" type="adml" lang="fi" />
+ <output filename="app/policy/windows/admx/fil/chrome.adml" type="adml" lang="fil" />
+ <output filename="app/policy/windows/admx/fr/chrome.adml" type="adml" lang="fr" />
+ <output filename="app/policy/windows/admx/gu/chrome.adml" type="adml" lang="gu" />
+ <output filename="app/policy/windows/admx/he/chrome.adml" type="adml" lang="he" />
+ <output filename="app/policy/windows/admx/hi/chrome.adml" type="adml" lang="hi" />
+ <output filename="app/policy/windows/admx/hr/chrome.adml" type="adml" lang="hr" />
+ <output filename="app/policy/windows/admx/hu/chrome.adml" type="adml" lang="hu" />
+ <output filename="app/policy/windows/admx/id/chrome.adml" type="adml" lang="id" />
+ <output filename="app/policy/windows/admx/it/chrome.adml" type="adml" lang="it" />
+ <output filename="app/policy/windows/admx/ja/chrome.adml" type="adml" lang="ja" />
+ <output filename="app/policy/windows/admx/kn/chrome.adml" type="adml" lang="kn" />
+ <output filename="app/policy/windows/admx/ko/chrome.adml" type="adml" lang="ko" />
+ <output filename="app/policy/windows/admx/lt/chrome.adml" type="adml" lang="lt" />
+ <output filename="app/policy/windows/admx/lv/chrome.adml" type="adml" lang="lv" />
+ <output filename="app/policy/windows/admx/ml/chrome.adml" type="adml" lang="ml" />
+ <output filename="app/policy/windows/admx/mr/chrome.adml" type="adml" lang="mr" />
+ <output filename="app/policy/windows/admx/ms/chrome.adml" type="adml" lang="ms" />
+ <output filename="app/policy/windows/admx/nl/chrome.adml" type="adml" lang="nl" />
+ <output filename="app/policy/windows/admx/nb/chrome.adml" type="adml" lang="no" />
+ <!-- 'no' for Norwegian Bokmål. It should be 'nb'. -->
+ <output filename="app/policy/windows/admx/pl/chrome.adml" type="adml" lang="pl" />
+ <output filename="app/policy/windows/admx/pt-BR/chrome.adml" type="adml" lang="pt-BR" />
+ <output filename="app/policy/windows/admx/pt-PT/chrome.adml" type="adml" lang="pt-PT" />
+ <output filename="app/policy/windows/admx/ro/chrome.adml" type="adml" lang="ro" />
+ <output filename="app/policy/windows/admx/ru/chrome.adml" type="adml" lang="ru" />
+ <output filename="app/policy/windows/admx/sk/chrome.adml" type="adml" lang="sk" />
+ <output filename="app/policy/windows/admx/sl/chrome.adml" type="adml" lang="sl" />
+ <output filename="app/policy/windows/admx/sr/chrome.adml" type="adml" lang="sr" />
+ <output filename="app/policy/windows/admx/sv/chrome.adml" type="adml" lang="sv" />
+ <output filename="app/policy/windows/admx/sw/chrome.adml" type="adml" lang="sw" />
+ <output filename="app/policy/windows/admx/ta/chrome.adml" type="adml" lang="ta" />
+ <output filename="app/policy/windows/admx/te/chrome.adml" type="adml" lang="te" />
+ <output filename="app/policy/windows/admx/th/chrome.adml" type="adml" lang="th" />
+ <output filename="app/policy/windows/admx/tr/chrome.adml" type="adml" lang="tr" />
+ <output filename="app/policy/windows/admx/uk/chrome.adml" type="adml" lang="uk" />
+ <output filename="app/policy/windows/admx/vi/chrome.adml" type="adml" lang="vi" />
+ <output filename="app/policy/windows/admx/zh-CN/chrome.adml" type="adml" lang="zh-CN" />
+ <output filename="app/policy/windows/admx/zh-TW/chrome.adml" type="adml" lang="zh-TW" />
+
+ <output filename="app/policy/windows/adm/am/chrome.adm" type="adm" lang="am" />
+ <output filename="app/policy/windows/adm/ar/chrome.adm" type="adm" lang="ar" />
+ <output filename="app/policy/windows/adm/bg/chrome.adm" type="adm" lang="bg" />
+ <output filename="app/policy/windows/adm/bn/chrome.adm" type="adm" lang="bn" />
+ <output filename="app/policy/windows/adm/ca/chrome.adm" type="adm" lang="ca" />
+ <output filename="app/policy/windows/adm/cs/chrome.adm" type="adm" lang="cs" />
+ <output filename="app/policy/windows/adm/da/chrome.adm" type="adm" lang="da" />
+ <output filename="app/policy/windows/adm/de/chrome.adm" type="adm" lang="de" />
+ <output filename="app/policy/windows/adm/el/chrome.adm" type="adm" lang="el" />
+ <output filename="app/policy/windows/adm/en-GB/chrome.adm" type="adm" lang="en-GB" />
+ <output filename="app/policy/windows/adm/en-US/chrome.adm" type="adm" lang="en" />
+ <output filename="app/policy/windows/adm/es/chrome.adm" type="adm" lang="es" />
+ <output filename="app/policy/windows/adm/es-419/chrome.adm" type="adm" lang="es-419" />
+ <output filename="app/policy/windows/adm/et/chrome.adm" type="adm" lang="et" />
+ <output filename="app/policy/windows/adm/fa/chrome.adm" type="adm" lang="fa" />
+ <output filename="app/policy/windows/adm/fi/chrome.adm" type="adm" lang="fi" />
+ <output filename="app/policy/windows/adm/fil/chrome.adm" type="adm" lang="fil" />
+ <output filename="app/policy/windows/adm/fr/chrome.adm" type="adm" lang="fr" />
+ <output filename="app/policy/windows/adm/gu/chrome.adm" type="adm" lang="gu" />
+ <output filename="app/policy/windows/adm/he/chrome.adm" type="adm" lang="he" />
+ <output filename="app/policy/windows/adm/hi/chrome.adm" type="adm" lang="hi" />
+ <output filename="app/policy/windows/adm/hr/chrome.adm" type="adm" lang="hr" />
+ <output filename="app/policy/windows/adm/hu/chrome.adm" type="adm" lang="hu" />
+ <output filename="app/policy/windows/adm/id/chrome.adm" type="adm" lang="id" />
+ <output filename="app/policy/windows/adm/it/chrome.adm" type="adm" lang="it" />
+ <output filename="app/policy/windows/adm/ja/chrome.adm" type="adm" lang="ja" />
+ <output filename="app/policy/windows/adm/kn/chrome.adm" type="adm" lang="kn" />
+ <output filename="app/policy/windows/adm/ko/chrome.adm" type="adm" lang="ko" />
+ <output filename="app/policy/windows/adm/lt/chrome.adm" type="adm" lang="lt" />
+ <output filename="app/policy/windows/adm/lv/chrome.adm" type="adm" lang="lv" />
+ <output filename="app/policy/windows/adm/ml/chrome.adm" type="adm" lang="ml" />
+ <output filename="app/policy/windows/adm/mr/chrome.adm" type="adm" lang="mr" />
+ <output filename="app/policy/windows/adm/ms/chrome.adm" type="adm" lang="ms" />
+ <output filename="app/policy/windows/adm/nl/chrome.adm" type="adm" lang="nl" />
+ <output filename="app/policy/windows/adm/nb/chrome.adm" type="adm" lang="no" />
+ <!-- 'no' for Norwegian Bokmål. It should be 'nb'. -->
+ <output filename="app/policy/windows/adm/pl/chrome.adm" type="adm" lang="pl" />
+ <output filename="app/policy/windows/adm/pt-BR/chrome.adm" type="adm" lang="pt-BR" />
+ <output filename="app/policy/windows/adm/pt-PT/chrome.adm" type="adm" lang="pt-PT" />
+ <output filename="app/policy/windows/adm/ro/chrome.adm" type="adm" lang="ro" />
+ <output filename="app/policy/windows/adm/ru/chrome.adm" type="adm" lang="ru" />
+ <output filename="app/policy/windows/adm/sk/chrome.adm" type="adm" lang="sk" />
+ <output filename="app/policy/windows/adm/sl/chrome.adm" type="adm" lang="sl" />
+ <output filename="app/policy/windows/adm/sr/chrome.adm" type="adm" lang="sr" />
+ <output filename="app/policy/windows/adm/sv/chrome.adm" type="adm" lang="sv" />
+ <output filename="app/policy/windows/adm/sw/chrome.adm" type="adm" lang="sw" />
+ <output filename="app/policy/windows/adm/ta/chrome.adm" type="adm" lang="ta" />
+ <output filename="app/policy/windows/adm/te/chrome.adm" type="adm" lang="te" />
+ <output filename="app/policy/windows/adm/th/chrome.adm" type="adm" lang="th" />
+ <output filename="app/policy/windows/adm/tr/chrome.adm" type="adm" lang="tr" />
+ <output filename="app/policy/windows/adm/uk/chrome.adm" type="adm" lang="uk" />
+ <output filename="app/policy/windows/adm/vi/chrome.adm" type="adm" lang="vi" />
+ <output filename="app/policy/windows/adm/zh-CN/chrome.adm" type="adm" lang="zh-CN" />
+ <output filename="app/policy/windows/adm/zh-TW/chrome.adm" type="adm" lang="zh-TW" />
+ </if>
+ <if expr="is_linux">
+ <output filename="app/policy/linux/examples/chrome.json" type="json" lang="en" />
+ </if>
+ <if expr="is_android">
+ <output filename="app/policy/android/values-v21/restriction_values.xml" type="android_policy" lang="en" />
+ </if>
+ <if expr="is_macosx">
+ <output filename="app/policy/mac/app-Manifest.plist" type="plist" lang="en" />
+
+ <!-- The following directory names use Mac language codes (en instead of en-US,
+ underscores instead of dashes. (As described in build/apply_locales.py -->
+ <output filename="app/policy/mac/strings/am.lproj/Localizable.strings" type="plist_strings" lang="am" />
+ <output filename="app/policy/mac/strings/ar.lproj/Localizable.strings" type="plist_strings" lang="ar" />
+ <output filename="app/policy/mac/strings/bg.lproj/Localizable.strings" type="plist_strings" lang="bg" />
+ <output filename="app/policy/mac/strings/bn.lproj/Localizable.strings" type="plist_strings" lang="bn" />
+ <output filename="app/policy/mac/strings/ca.lproj/Localizable.strings" type="plist_strings" lang="ca" />
+ <output filename="app/policy/mac/strings/cs.lproj/Localizable.strings" type="plist_strings" lang="cs" />
+ <output filename="app/policy/mac/strings/da.lproj/Localizable.strings" type="plist_strings" lang="da" />
+ <output filename="app/policy/mac/strings/de.lproj/Localizable.strings" type="plist_strings" lang="de" />
+ <output filename="app/policy/mac/strings/el.lproj/Localizable.strings" type="plist_strings" lang="el" />
+ <output filename="app/policy/mac/strings/en_GB.lproj/Localizable.strings" type="plist_strings" lang="en-GB" />
+ <output filename="app/policy/mac/strings/en.lproj/Localizable.strings" type="plist_strings" lang="en" />
+ <output filename="app/policy/mac/strings/es.lproj/Localizable.strings" type="plist_strings" lang="es" />
+ <output filename="app/policy/mac/strings/es_419.lproj/Localizable.strings" type="plist_strings" lang="es-419" />
+ <output filename="app/policy/mac/strings/et.lproj/Localizable.strings" type="plist_strings" lang="et" />
+ <output filename="app/policy/mac/strings/fa.lproj/Localizable.strings" type="plist_strings" lang="fa" />
+ <output filename="app/policy/mac/strings/fi.lproj/Localizable.strings" type="plist_strings" lang="fi" />
+ <output filename="app/policy/mac/strings/fil.lproj/Localizable.strings" type="plist_strings" lang="fil" />
+ <output filename="app/policy/mac/strings/fr.lproj/Localizable.strings" type="plist_strings" lang="fr" />
+ <output filename="app/policy/mac/strings/gu.lproj/Localizable.strings" type="plist_strings" lang="gu" />
+ <output filename="app/policy/mac/strings/he.lproj/Localizable.strings" type="plist_strings" lang="he" />
+ <output filename="app/policy/mac/strings/hi.lproj/Localizable.strings" type="plist_strings" lang="hi" />
+ <output filename="app/policy/mac/strings/hr.lproj/Localizable.strings" type="plist_strings" lang="hr" />
+ <output filename="app/policy/mac/strings/hu.lproj/Localizable.strings" type="plist_strings" lang="hu" />
+ <output filename="app/policy/mac/strings/id.lproj/Localizable.strings" type="plist_strings" lang="id" />
+ <output filename="app/policy/mac/strings/it.lproj/Localizable.strings" type="plist_strings" lang="it" />
+ <output filename="app/policy/mac/strings/ja.lproj/Localizable.strings" type="plist_strings" lang="ja" />
+ <output filename="app/policy/mac/strings/kn.lproj/Localizable.strings" type="plist_strings" lang="kn" />
+ <output filename="app/policy/mac/strings/ko.lproj/Localizable.strings" type="plist_strings" lang="ko" />
+ <output filename="app/policy/mac/strings/lt.lproj/Localizable.strings" type="plist_strings" lang="lt" />
+ <output filename="app/policy/mac/strings/lv.lproj/Localizable.strings" type="plist_strings" lang="lv" />
+ <output filename="app/policy/mac/strings/ml.lproj/Localizable.strings" type="plist_strings" lang="ml" />
+ <output filename="app/policy/mac/strings/mr.lproj/Localizable.strings" type="plist_strings" lang="mr" />
+ <output filename="app/policy/mac/strings/ms.lproj/Localizable.strings" type="plist_strings" lang="ms" />
+ <output filename="app/policy/mac/strings/nl.lproj/Localizable.strings" type="plist_strings" lang="nl" />
+ <output filename="app/policy/mac/strings/nb.lproj/Localizable.strings" type="plist_strings" lang="no" />
+ <!-- 'no' for Norwegian Bokmål. It should be 'nb'. -->
+ <output filename="app/policy/mac/strings/pl.lproj/Localizable.strings" type="plist_strings" lang="pl" />
+ <output filename="app/policy/mac/strings/pt_BR.lproj/Localizable.strings" type="plist_strings" lang="pt-BR" />
+ <output filename="app/policy/mac/strings/pt_PT.lproj/Localizable.strings" type="plist_strings" lang="pt-PT" />
+ <output filename="app/policy/mac/strings/ro.lproj/Localizable.strings" type="plist_strings" lang="ro" />
+ <output filename="app/policy/mac/strings/ru.lproj/Localizable.strings" type="plist_strings" lang="ru" />
+ <output filename="app/policy/mac/strings/sk.lproj/Localizable.strings" type="plist_strings" lang="sk" />
+ <output filename="app/policy/mac/strings/sl.lproj/Localizable.strings" type="plist_strings" lang="sl" />
+ <output filename="app/policy/mac/strings/sr.lproj/Localizable.strings" type="plist_strings" lang="sr" />
+ <output filename="app/policy/mac/strings/sv.lproj/Localizable.strings" type="plist_strings" lang="sv" />
+ <output filename="app/policy/mac/strings/sw.lproj/Localizable.strings" type="plist_strings" lang="sw" />
+ <output filename="app/policy/mac/strings/ta.lproj/Localizable.strings" type="plist_strings" lang="ta" />
+ <output filename="app/policy/mac/strings/te.lproj/Localizable.strings" type="plist_strings" lang="te" />
+ <output filename="app/policy/mac/strings/th.lproj/Localizable.strings" type="plist_strings" lang="th" />
+ <output filename="app/policy/mac/strings/tr.lproj/Localizable.strings" type="plist_strings" lang="tr" />
+ <output filename="app/policy/mac/strings/uk.lproj/Localizable.strings" type="plist_strings" lang="uk" />
+ <output filename="app/policy/mac/strings/vi.lproj/Localizable.strings" type="plist_strings" lang="vi" />
+ <output filename="app/policy/mac/strings/zh_CN.lproj/Localizable.strings" type="plist_strings" lang="zh-CN" />
+ <output filename="app/policy/mac/strings/zh_TW.lproj/Localizable.strings" type="plist_strings" lang="zh-TW" />
+
+ <!-- Generate the sample iOS plist when building the templates for the Mac. -->
+ <output filename="app/policy/ios/chrome_policy.plist" type="ios_plist" lang="en" />
+ </if>
+ </outputs>
+ <translations>
+ <file path="policy_templates_am.xtb" lang="am" />
+ <file path="policy_templates_ar.xtb" lang="ar" />
+ <file path="policy_templates_bg.xtb" lang="bg" />
+ <file path="policy_templates_bn.xtb" lang="bn" />
+ <file path="policy_templates_ca.xtb" lang="ca" />
+ <file path="policy_templates_cs.xtb" lang="cs" />
+ <file path="policy_templates_da.xtb" lang="da" />
+ <file path="policy_templates_de.xtb" lang="de" />
+ <file path="policy_templates_el.xtb" lang="el" />
+ <file path="policy_templates_en-GB.xtb" lang="en-GB" />
+ <file path="policy_templates_es.xtb" lang="es" />
+ <file path="policy_templates_es-419.xtb" lang="es-419" />
+ <file path="policy_templates_et.xtb" lang="et" />
+ <file path="policy_templates_fa.xtb" lang="fa" />
+ <file path="policy_templates_fi.xtb" lang="fi" />
+ <file path="policy_templates_fil.xtb" lang="fil" />
+ <file path="policy_templates_fr.xtb" lang="fr" />
+ <file path="policy_templates_gu.xtb" lang="gu" />
+ <file path="policy_templates_hi.xtb" lang="hi" />
+ <file path="policy_templates_hr.xtb" lang="hr" />
+ <file path="policy_templates_hu.xtb" lang="hu" />
+ <file path="policy_templates_id.xtb" lang="id" />
+ <file path="policy_templates_it.xtb" lang="it" />
+ <!-- The translation console uses 'iw' for Hebrew, but we use 'he'. -->
+ <file path="policy_templates_iw.xtb" lang="he" />
+ <file path="policy_templates_ja.xtb" lang="ja" />
+ <file path="policy_templates_kn.xtb" lang="kn" />
+ <file path="policy_templates_ko.xtb" lang="ko" />
+ <file path="policy_templates_lt.xtb" lang="lt" />
+ <file path="policy_templates_lv.xtb" lang="lv" />
+ <file path="policy_templates_ml.xtb" lang="ml" />
+ <file path="policy_templates_mr.xtb" lang="mr" />
+ <file path="policy_templates_ms.xtb" lang="ms" />
+ <file path="policy_templates_nl.xtb" lang="nl" />
+ <file path="policy_templates_no.xtb" lang="no" />
+ <file path="policy_templates_pl.xtb" lang="pl" />
+ <file path="policy_templates_pt-BR.xtb" lang="pt-BR" />
+ <file path="policy_templates_pt-PT.xtb" lang="pt-PT" />
+ <file path="policy_templates_ro.xtb" lang="ro" />
+ <file path="policy_templates_ru.xtb" lang="ru" />
+ <file path="policy_templates_sk.xtb" lang="sk" />
+ <file path="policy_templates_sl.xtb" lang="sl" />
+ <file path="policy_templates_sr.xtb" lang="sr" />
+ <file path="policy_templates_sv.xtb" lang="sv" />
+ <file path="policy_templates_sw.xtb" lang="sw" />
+ <file path="policy_templates_ta.xtb" lang="ta" />
+ <file path="policy_templates_te.xtb" lang="te" />
+ <file path="policy_templates_th.xtb" lang="th" />
+ <file path="policy_templates_tr.xtb" lang="tr" />
+ <file path="policy_templates_uk.xtb" lang="uk" />
+ <file path="policy_templates_vi.xtb" lang="vi" />
+ <file path="policy_templates_zh-CN.xtb" lang="zh-CN" />
+ <file path="policy_templates_zh-TW.xtb" lang="zh-TW" />
+ </translations>
+ <release seq="1" allow_pseudo="false">
+ <structures fallback_to_english="true">
+ <!-- List of policies and placeholder texts. This item should precede any
+ message definitions. -->
+ <structure name="IDD_POLICY_SOURCE_FILE" file="policy_templates.json" type="policy_template_metafile" />
+ </structures>
+ </release>
+</grit>
diff --git a/chromium/components/policy_strings.grdp b/chromium/components/policy_strings.grdp
index 8433599b2dd..f9701ceec4e 100644
--- a/chromium/components/policy_strings.grdp
+++ b/chromium/components/policy_strings.grdp
@@ -291,6 +291,9 @@
<message name="IDS_POLICY_HEADER_STATUS" desc="Table header for the column in policy table that contains the policy status.">
Status
</message>
+ <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>
@@ -319,4 +322,16 @@
<message name="IDS_POLICY_INVALID_BOOKMARK" desc="Text displayed in the status column when an entry of the ManagedBookmarks policy is not a valid bookmark.">
Ignored invalid bookmark at index <ph name="ENTRY_INDEX">$1<ex>3</ex></ph>
</message>
+ <message name="IDS_POLICY_SOURCE_ENTERPRISE_DEFAULT" desc="Indicates that a policy is set by default in an enterprise environment and can be overridden (for Chrome OS only).">
+ Enterprise default
+ </message>
+ <message name="IDS_POLICY_SOURCE_CLOUD" desc="Indicates that the policy originates from the cloud.">
+ Cloud
+ </message>
+ <message name="IDS_POLICY_SOURCE_PLATFORM" desc="Indicates that the policy is obtained from the local OS.">
+ Platform
+ </message>
+ <message name="IDS_POLICY_SOURCE_ENTERPRISE_OVERRIDE" desc="Indicates that a policy is enforced in an enterprise environment and can not be overridden (for Chrome OS only).">
+ Enterprise override
+ </message>
</grit-part>
diff --git a/chromium/components/precache.gypi b/chromium/components/precache.gypi
index aabe44548be..fb9c3c288f9 100644
--- a/chromium/components/precache.gypi
+++ b/chromium/components/precache.gypi
@@ -11,6 +11,7 @@
'dependencies': [
'precache_core',
'../base/base.gyp:base',
+ '../components/components.gyp:sync_driver',
'../content/content.gyp:content_browser',
'../url/url.gyp:url_lib',
],
diff --git a/chromium/components/pref_registry.gypi b/chromium/components/pref_registry.gypi
index 86dfdce93cc..5ff32c38a7c 100644
--- a/chromium/components/pref_registry.gypi
+++ b/chromium/components/pref_registry.gypi
@@ -7,7 +7,7 @@
{
# GN version: //components/pref_registry
'target_name': 'pref_registry',
- 'type': '<(component)',
+ 'type': 'static_library',
'dependencies': [
'../base/base.gyp:base',
'../base/base.gyp:base_prefs',
@@ -16,11 +16,7 @@
'include_dirs': [
'..',
],
- 'defines': [
- 'PREF_REGISTRY_IMPLEMENTATION',
- ],
'sources': [
- 'pref_registry/pref_registry_export.h',
'pref_registry/pref_registry_syncable.cc',
'pref_registry/pref_registry_syncable.h',
],
diff --git a/chromium/components/pref_registry/BUILD.gn b/chromium/components/pref_registry/BUILD.gn
new file mode 100644
index 00000000000..abeeb54c395
--- /dev/null
+++ b/chromium/components/pref_registry/BUILD.gn
@@ -0,0 +1,32 @@
+# 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.
+
+source_set("pref_registry") {
+ sources = [
+ "pref_registry_syncable.cc",
+ "pref_registry_syncable.h",
+ ]
+
+ deps = [
+ "//base",
+ "//base:prefs",
+ "//base/third_party/dynamic_annotations",
+ "//ui/base",
+ ]
+}
+
+source_set("test_support") {
+ testonly = true
+ sources = [
+ "testing_pref_service_syncable.cc",
+ "testing_pref_service_syncable.h",
+ ]
+
+ deps = [
+ ":pref_registry",
+ "//base",
+ "//base:prefs",
+ "//base:prefs_test_support",
+ ]
+}
diff --git a/chromium/components/pref_registry/DEPS b/chromium/components/pref_registry/DEPS
new file mode 100644
index 00000000000..e7cf2c6ff61
--- /dev/null
+++ b/chromium/components/pref_registry/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+ui/base",
+]
diff --git a/chromium/components/pref_registry/OWNERS b/chromium/components/pref_registry/OWNERS
new file mode 100644
index 00000000000..2d870381cb7
--- /dev/null
+++ b/chromium/components/pref_registry/OWNERS
@@ -0,0 +1,4 @@
+battre@chromium.org
+bauerb@chromium.org
+gab@chromium.org
+pam@chromium.org
diff --git a/chromium/components/pref_registry/README b/chromium/components/pref_registry/README
new file mode 100644
index 00000000000..041a10309f0
--- /dev/null
+++ b/chromium/components/pref_registry/README
@@ -0,0 +1,6 @@
+The //components/pref_registry component provides:
+
+A place for PrefRegistrySyncable to live, where it can be used by
+components that need to register preferences associated with users.
+
+This component should not depend on content module.
diff --git a/chromium/components/pref_registry/pref_registry_syncable.cc b/chromium/components/pref_registry/pref_registry_syncable.cc
new file mode 100644
index 00000000000..bb90417d33d
--- /dev/null
+++ b/chromium/components/pref_registry/pref_registry_syncable.cc
@@ -0,0 +1,49 @@
+// 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/pref_registry/pref_registry_syncable.h"
+
+#include "base/files/file_path.h"
+#include "base/prefs/default_pref_store.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/values.h"
+
+namespace user_prefs {
+
+PrefRegistrySyncable::PrefRegistrySyncable() {
+}
+
+PrefRegistrySyncable::~PrefRegistrySyncable() {
+}
+
+void PrefRegistrySyncable::SetSyncableRegistrationCallback(
+ const SyncableRegistrationCallback& cb) {
+ callback_ = cb;
+}
+
+void PrefRegistrySyncable::OnPrefRegistered(const std::string& path,
+ base::Value* default_value,
+ uint32 flags) {
+ // Tests that |flags| does not contain both SYNCABLE_PREF and
+ // SYNCABLE_PRIORITY_PREF flags at the same time.
+ DCHECK(!(flags & PrefRegistrySyncable::SYNCABLE_PREF) ||
+ !(flags & PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF));
+
+ if (flags & PrefRegistrySyncable::SYNCABLE_PREF ||
+ flags & PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF) {
+ if (!callback_.is_null())
+ callback_.Run(path, flags);
+ }
+}
+
+scoped_refptr<PrefRegistrySyncable> PrefRegistrySyncable::ForkForIncognito() {
+ // TODO(joi): We can directly reuse the same PrefRegistry once
+ // PrefService no longer registers for callbacks on registration and
+ // unregistration.
+ scoped_refptr<PrefRegistrySyncable> registry(new PrefRegistrySyncable());
+ registry->defaults_ = defaults_;
+ return registry;
+}
+
+} // namespace user_prefs
diff --git a/chromium/components/pref_registry/pref_registry_syncable.h b/chromium/components/pref_registry/pref_registry_syncable.h
new file mode 100644
index 00000000000..3a0b1d681bb
--- /dev/null
+++ b/chromium/components/pref_registry/pref_registry_syncable.h
@@ -0,0 +1,89 @@
+// 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_PREF_REGISTRY_PREF_REGISTRY_SYNCABLE_H_
+#define COMPONENTS_PREF_REGISTRY_PREF_REGISTRY_SYNCABLE_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/prefs/pref_registry_simple.h"
+
+namespace base {
+class DictionaryValue;
+class FilePath;
+class ListValue;
+class Value;
+}
+
+// TODO(tfarina): Change this namespace to pref_registry.
+namespace user_prefs {
+
+// A PrefRegistry that forces users to choose whether each registered
+// preference is syncable or not.
+//
+// Classes or components that want to register such preferences should
+// define a static function named RegisterUserPrefs that takes a
+// PrefRegistrySyncable*, and the top-level application using the
+// class or embedding the component should call this function at an
+// appropriate time before the PrefService for these preferences is
+// constructed. See e.g. chrome/browser/prefs/browser_prefs.cc which
+// does this for Chrome.
+//
+// TODO(raymes): This class only exists to support SyncableRegistrationCallback
+// logic which is only required to support pref registration after the
+// PrefService has been created which is only used by tests. We can remove this
+// entire class and those tests with some work.
+class PrefRegistrySyncable : public PrefRegistrySimple {
+ public:
+ // Enum of flags used when registering preferences to determine if it should
+ // be synced or not. These flags are mutually exclusive, only one of them
+ // should ever be specified.
+ //
+ // Note: These must NOT overlap with PrefRegistry::PrefRegistrationFlags.
+ enum PrefRegistrationFlags : uint32 {
+ // The pref will be synced.
+ SYNCABLE_PREF = 1 << 0,
+
+ // The pref will be synced. The pref will never be encrypted and will be
+ // synced before other datatypes. Because they're never encrypted, on first
+ // sync, they can be synced down before the user is prompted for a
+ // passphrase.
+ SYNCABLE_PRIORITY_PREF = 1 << 1,
+ };
+
+ typedef base::Callback<void(const std::string& path, uint32 flags)>
+ SyncableRegistrationCallback;
+
+ PrefRegistrySyncable();
+
+ // Exactly one callback can be set for the event of a syncable
+ // preference being registered. It will be fired after the
+ // registration has occurred.
+ //
+ // Calling this method after a callback has already been set will
+ // make the object forget the previous callback and use the new one
+ // instead.
+ void SetSyncableRegistrationCallback(const SyncableRegistrationCallback& cb);
+
+ // Returns a new PrefRegistrySyncable that uses the same defaults
+ // store.
+ scoped_refptr<PrefRegistrySyncable> ForkForIncognito();
+
+ private:
+ ~PrefRegistrySyncable() override;
+
+ // PrefRegistrySimple overrides.
+ void OnPrefRegistered(const std::string& path,
+ base::Value* default_value,
+ uint32 flags) override;
+
+ SyncableRegistrationCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefRegistrySyncable);
+};
+
+} // namespace user_prefs
+
+#endif // COMPONENTS_PREF_REGISTRY_PREF_REGISTRY_SYNCABLE_H_
diff --git a/chromium/components/pref_registry/testing_pref_service_syncable.cc b/chromium/components/pref_registry/testing_pref_service_syncable.cc
new file mode 100644
index 00000000000..22602936c69
--- /dev/null
+++ b/chromium/components/pref_registry/testing_pref_service_syncable.cc
@@ -0,0 +1,70 @@
+// 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/pref_registry/testing_pref_service_syncable.h"
+
+#include "base/bind.h"
+#include "base/prefs/pref_notifier_impl.h"
+#include "base/prefs/pref_value_store.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+
+template <>
+TestingPrefServiceBase<PrefService, user_prefs::PrefRegistrySyncable>::
+ TestingPrefServiceBase(TestingPrefStore* managed_prefs,
+ TestingPrefStore* user_prefs,
+ TestingPrefStore* recommended_prefs,
+ user_prefs::PrefRegistrySyncable* pref_registry,
+ PrefNotifierImpl* pref_notifier)
+ : PrefService(pref_notifier,
+ new PrefValueStore(managed_prefs,
+ NULL, // supervised_user_prefs
+ NULL, // extension_prefs
+ NULL, // command_line_prefs
+ user_prefs,
+ recommended_prefs,
+ pref_registry->defaults().get(),
+ pref_notifier),
+ user_prefs,
+ pref_registry,
+ base::Bind(&TestingPrefServiceBase<
+ PrefService,
+ user_prefs::PrefRegistrySyncable>::HandleReadError),
+ false),
+ managed_prefs_(managed_prefs),
+ user_prefs_(user_prefs),
+ recommended_prefs_(recommended_prefs) {}
+
+namespace user_prefs {
+
+TestingPrefServiceSyncable::TestingPrefServiceSyncable()
+ : TestingPrefServiceBase<PrefService, PrefRegistrySyncable>(
+ new TestingPrefStore(),
+ new TestingPrefStore(),
+ new TestingPrefStore(),
+ new PrefRegistrySyncable(),
+ new PrefNotifierImpl()) {
+}
+
+TestingPrefServiceSyncable::TestingPrefServiceSyncable(
+ TestingPrefStore* managed_prefs,
+ TestingPrefStore* user_prefs,
+ TestingPrefStore* recommended_prefs,
+ PrefRegistrySyncable* pref_registry,
+ PrefNotifierImpl* pref_notifier)
+ : TestingPrefServiceBase<PrefService, PrefRegistrySyncable>(
+ managed_prefs,
+ user_prefs,
+ recommended_prefs,
+ pref_registry,
+ pref_notifier) {
+}
+
+TestingPrefServiceSyncable::~TestingPrefServiceSyncable() {
+}
+
+PrefRegistrySyncable* TestingPrefServiceSyncable::registry() {
+ return static_cast<PrefRegistrySyncable*>(DeprecatedGetPrefRegistry());
+}
+
+} // namespace user_prefs
diff --git a/chromium/components/pref_registry/testing_pref_service_syncable.h b/chromium/components/pref_registry/testing_pref_service_syncable.h
new file mode 100644
index 00000000000..22c8a573eda
--- /dev/null
+++ b/chromium/components/pref_registry/testing_pref_service_syncable.h
@@ -0,0 +1,38 @@
+// 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_PERF_REGISTRY_TESTING_PREF_SERVICE_SYNCABLE_H_
+#define COMPONENTS_PERF_REGISTRY_TESTING_PREF_SERVICE_SYNCABLE_H_
+
+#include "base/basictypes.h"
+#include "base/prefs/testing_pref_service.h"
+
+namespace user_prefs {
+
+class PrefRegistrySyncable;
+
+// Test version of PrefServiceSyncable.
+class TestingPrefServiceSyncable
+ : public TestingPrefServiceBase<PrefService, PrefRegistrySyncable> {
+ public:
+ TestingPrefServiceSyncable();
+ TestingPrefServiceSyncable(TestingPrefStore* managed_prefs,
+ TestingPrefStore* user_prefs,
+ TestingPrefStore* recommended_prefs,
+ PrefRegistrySyncable* pref_registry,
+ PrefNotifierImpl* pref_notifier);
+ ~TestingPrefServiceSyncable() override;
+
+ // This is provided as a convenience; on a production PrefService
+ // you would do all registrations before constructing it, passing it
+ // a PrefRegistry via its constructor (or via e.g. PrefServiceFactory).
+ PrefRegistrySyncable* registry();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestingPrefServiceSyncable);
+};
+
+} // namespace user_prefs
+
+#endif // COMPONENTS_PERF_REGISTRY_TESTING_PREF_SERVICE_SYNCABLE_H_
diff --git a/chromium/components/printing.gypi b/chromium/components/printing.gypi
index d9244f0a157..a85abfe59e6 100644
--- a/chromium/components/printing.gypi
+++ b/chromium/components/printing.gypi
@@ -46,10 +46,25 @@
# TODO(dgn): C4267: http://crbug.com/167187 size_t -> int
'msvs_disabled_warnings': [ 4267 ],
},{
+ # GN: //components/printing/browser:printing_browser
+ 'target_name': 'printing_browser',
+ 'type': 'static_library',
+ 'dependencies': [
+ '<(DEPTH)/printing/printing.gyp:printing',
+ '<(DEPTH)/skia/skia.gyp:skia',
+ ],
+ 'sources': [
+ 'printing/browser/print_manager.cc',
+ 'printing/browser/print_manager.h',
+ 'printing/browser/print_manager_utils.cc',
+ 'printing/browser/print_manager_utils.h',
+ ],
+ },{
# GN: //components/printing/test:printing_test_support
'target_name': 'printing_test_support',
'type': 'static_library',
'dependencies': [
+ '../skia/skia.gyp:skia',
'<(DEPTH)/testing/gtest.gyp:gtest',
'printing_renderer',
],
diff --git a/chromium/components/printing/browser/BUILD.gn b/chromium/components/printing/browser/BUILD.gn
new file mode 100644
index 00000000000..b0cde36a97a
--- /dev/null
+++ b/chromium/components/printing/browser/BUILD.gn
@@ -0,0 +1,16 @@
+# 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.
+
+source_set("browser") {
+ sources = [
+ "print_manager.cc",
+ "print_manager.h",
+ "print_manager_utils.cc",
+ "print_manager_utils.h",
+ ]
+ deps = [
+ "//content/public/browser",
+ "//printing",
+ ]
+}
diff --git a/chromium/components/printing/browser/print_manager.cc b/chromium/components/printing/browser/print_manager.cc
new file mode 100644
index 00000000000..7e80befe310
--- /dev/null
+++ b/chromium/components/printing/browser/print_manager.cc
@@ -0,0 +1,69 @@
+// 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/printing/browser/print_manager.h"
+
+#include "components/printing/common/print_messages.h"
+
+namespace printing {
+
+PrintManager::PrintManager(content::WebContents* contents)
+ : content::WebContentsObserver(contents),
+ number_pages_(0),
+ cookie_(0) {
+}
+
+PrintManager::~PrintManager() {
+}
+
+bool PrintManager::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PrintManager, message)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount,
+ OnDidGetPrintedPagesCount)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDocumentCookie,
+ OnDidGetDocumentCookie)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed, OnPrintingFailed)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void PrintManager::OnDidGetPrintedPagesCount(int cookie,
+ int number_pages) {
+ DCHECK_GT(cookie, 0);
+ DCHECK_GT(number_pages, 0);
+ number_pages_ = number_pages;
+}
+
+void PrintManager::OnDidGetDocumentCookie(int cookie) {
+ cookie_ = cookie;
+}
+
+void PrintManager::OnPrintingFailed(int cookie) {
+ if (cookie != cookie_) {
+ NOTREACHED();
+ return;
+ }
+#if defined(OS_ANDROID)
+ PdfWritingDone(false);
+#endif
+}
+
+void PrintManager::RenderProcessGone(base::TerminationStatus status) {
+#if defined(OS_ANDROID)
+ PdfWritingDone(false);
+#endif
+}
+
+#if defined(OS_ANDROID)
+void PrintManager::PdfWritingDone(bool result) {
+ if (!pdf_writing_done_callback_.is_null())
+ pdf_writing_done_callback_.Run(file_descriptor().fd, result);
+ // Invalidate the file descriptor so it doesn't get reused.
+ file_descriptor_ = base::FileDescriptor(-1, false);
+}
+#endif
+
+} // namespace printing
diff --git a/chromium/components/printing/browser/print_manager.h b/chromium/components/printing/browser/print_manager.h
new file mode 100644
index 00000000000..ea24f5152ac
--- /dev/null
+++ b/chromium/components/printing/browser/print_manager.h
@@ -0,0 +1,68 @@
+// 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_PRINTING_BROWSER_PRINT_MANAGER_H_
+#define COMPONENTS_PRINTING_BROWSER_PRINT_MANAGER_H_
+
+#include "content/public/browser/web_contents_observer.h"
+
+#if defined(OS_ANDROID)
+#include "base/callback.h"
+#include "base/file_descriptor_posix.h"
+#endif
+
+namespace printing {
+
+class PrintManager : public content::WebContentsObserver {
+ public:
+ ~PrintManager() override;
+
+#if defined(OS_ANDROID)
+ // TODO(timvolodine): consider introducing PrintManagerAndroid (crbug/500960)
+ typedef base::Callback<void(int, bool)> PdfWritingDoneCallback;
+
+ void PdfWritingDone(bool result);
+
+ // Sets the file descriptor into which the PDF will be written.
+ void set_file_descriptor(const base::FileDescriptor& file_descriptor) {
+ file_descriptor_ = file_descriptor;
+ }
+
+ // Gets the file descriptor into which the PDF will be written.
+ base::FileDescriptor file_descriptor() const { return file_descriptor_; }
+#endif
+
+ protected:
+ explicit PrintManager(content::WebContents* contents);
+
+ // Terminates or cancels the print job if one was pending.
+ void RenderProcessGone(base::TerminationStatus status) override;
+
+ // content::WebContentsObserver
+ bool OnMessageReceived(const IPC::Message& message) override;
+
+ // IPC handlers
+ virtual void OnDidGetPrintedPagesCount(int cookie, int number_pages);
+ virtual void OnPrintingFailed(int cookie);
+
+ int number_pages_; // Number of pages to print in the print job.
+ int cookie_; // The current document cookie.
+
+#if defined(OS_ANDROID)
+ // The file descriptor into which the PDF of the page will be written.
+ base::FileDescriptor file_descriptor_;
+
+ // Callback to execute when done writing pdf.
+ PdfWritingDoneCallback pdf_writing_done_callback_;
+#endif
+
+ private:
+ void OnDidGetDocumentCookie(int cookie);
+
+ DISALLOW_COPY_AND_ASSIGN(PrintManager);
+};
+
+} // namespace printing
+
+#endif // COMPONENTS_PRINTING_BROWSER_PRINT_MANAGER_H_
diff --git a/chromium/components/printing/browser/print_manager_utils.cc b/chromium/components/printing/browser/print_manager_utils.cc
new file mode 100644
index 00000000000..7d9df745fe2
--- /dev/null
+++ b/chromium/components/printing/browser/print_manager_utils.cc
@@ -0,0 +1,41 @@
+// 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/printing/browser/print_manager_utils.h"
+#include "components/printing/common/print_messages.h"
+#include "printing/print_settings.h"
+
+namespace printing {
+
+void RenderParamsFromPrintSettings(const PrintSettings& settings,
+ PrintMsg_Print_Params* params) {
+ params->page_size = settings.page_setup_device_units().physical_size();
+ params->content_size.SetSize(
+ settings.page_setup_device_units().content_area().width(),
+ settings.page_setup_device_units().content_area().height());
+ params->printable_area.SetRect(
+ settings.page_setup_device_units().printable_area().x(),
+ settings.page_setup_device_units().printable_area().y(),
+ settings.page_setup_device_units().printable_area().width(),
+ settings.page_setup_device_units().printable_area().height());
+ params->margin_top = settings.page_setup_device_units().content_area().y();
+ params->margin_left = settings.page_setup_device_units().content_area().x();
+ params->dpi = settings.dpi();
+ // Currently hardcoded at 1.25. See PrintSettings' constructor.
+ params->min_shrink = settings.min_shrink();
+ // Currently hardcoded at 2.0. See PrintSettings' constructor.
+ params->max_shrink = settings.max_shrink();
+ // Currently hardcoded at 72dpi. See PrintSettings' constructor.
+ params->desired_dpi = settings.desired_dpi();
+ // Always use an invalid cookie.
+ params->document_cookie = 0;
+ params->selection_only = settings.selection_only();
+ params->supports_alpha_blend = settings.supports_alpha_blend();
+ params->should_print_backgrounds = settings.should_print_backgrounds();
+ params->display_header_footer = settings.display_header_footer();
+ params->title = settings.title();
+ params->url = settings.url();
+}
+
+} // namespace printing
diff --git a/chromium/components/printing/browser/print_manager_utils.h b/chromium/components/printing/browser/print_manager_utils.h
new file mode 100644
index 00000000000..31e0daaad6b
--- /dev/null
+++ b/chromium/components/printing/browser/print_manager_utils.h
@@ -0,0 +1,21 @@
+// 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_PRINTING_BROWSER_PRINT_MANAGER_UTILS_H_
+#define COMPONENTS_PRINTING_BROWSER_PRINT_MANAGER_UTILS_H_
+
+struct PrintMsg_Print_Params;
+
+namespace printing {
+
+class PrintSettings;
+
+// Converts given settings to Print_Params and stores them in the output
+// parameter |params|.
+void RenderParamsFromPrintSettings(const PrintSettings& settings,
+ PrintMsg_Print_Params* params);
+
+} // namespace printing
+
+#endif // COMPONENTS_PRINTING_BROWSER_PRINT_MANAGER_UTILS_H_
diff --git a/chromium/components/printing/common/BUILD.gn b/chromium/components/printing/common/BUILD.gn
index d56e4e2b80f..0bc56692c34 100644
--- a/chromium/components/printing/common/BUILD.gn
+++ b/chromium/components/printing/common/BUILD.gn
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-static_library("printing_common") {
+source_set("common") {
sources = [
"print_messages.cc",
"print_messages.h",
diff --git a/chromium/components/printing/common/print_messages.h b/chromium/components/printing/common/print_messages.h
index 058c237654d..34d9613e92d 100644
--- a/chromium/components/printing/common/print_messages.h
+++ b/chromium/components/printing/common/print_messages.h
@@ -371,7 +371,7 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetDocumentCookie,
IPC_MESSAGE_ROUTED0(PrintHostMsg_DidShowPrintDialog)
// Sends back to the browser the rendered "printed page" that was requested by
-// a ViewMsg_PrintPage message or from scripted printing. The memory handle in
+// a PrintMsg_PrintPages message or from scripted printing. The memory handle in
// this message is already valid in the browser process.
IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPrintPage,
PrintHostMsg_DidPrintPage_Params /* page content */)
@@ -391,7 +391,7 @@ IPC_SYNC_MESSAGE_ROUTED2_2(PrintHostMsg_UpdatePrintSettings,
// It's the renderer that controls the printing process when it is generated
// by javascript. This step is about showing UI to the user to select the
// final print settings. The output parameter is the same as
-// ViewMsg_PrintPages which is executed implicitly.
+// PrintMsg_PrintPages which is executed implicitly.
IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_ScriptedPrint,
PrintHostMsg_ScriptedPrint_Params,
PrintMsg_PrintPages_Params
@@ -403,10 +403,10 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_ScriptedPrint,
IPC_SYNC_MESSAGE_CONTROL1_2(PrintHostMsg_AllocateTempFileForPrinting,
int /* render_view_id */,
base::FileDescriptor /* temp file fd */,
- int /* fd in browser*/) // Used only by Chrome OS.
+ int /* fd in browser*/) // Used only by Chrome OS.
IPC_MESSAGE_CONTROL2(PrintHostMsg_TempFileForPrintingWritten,
int /* render_view_id */,
- int /* fd in browser */) // Used only by Chrome OS.
+ int /* fd in browser */) // Used only by Chrome OS.
#endif
// Asks the browser to do print preview.
diff --git a/chromium/components/printing/renderer/BUILD.gn b/chromium/components/printing/renderer/BUILD.gn
index c31bb8e980e..92670027d77 100644
--- a/chromium/components/printing/renderer/BUILD.gn
+++ b/chromium/components/printing/renderer/BUILD.gn
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-static_library("printing_renderer") {
+source_set("renderer") {
sources = [
"print_web_view_helper.cc",
"print_web_view_helper.h",
@@ -17,7 +17,7 @@ static_library("printing_renderer") {
deps = [
"//base",
- "//components/printing/common:printing_common",
+ "//components/printing/common",
"//components/resources",
"//content/public/common",
"//content/public/renderer",
diff --git a/chromium/components/printing/renderer/print_web_view_helper.cc b/chromium/components/printing/renderer/print_web_view_helper.cc
index d315efae36a..27419d64229 100644
--- a/chromium/components/printing/renderer/print_web_view_helper.cc
+++ b/chromium/components/printing/renderer/print_web_view_helper.cc
@@ -71,10 +71,8 @@ enum PrintPreviewHelperEvents {
const double kMinDpi = 1.0;
-#if !defined(ENABLE_PRINT_PREVIEW)
-bool g_is_preview_enabled_ = false;
-#else
-bool g_is_preview_enabled_ = true;
+#if defined(ENABLE_PRINT_PREVIEW)
+bool g_is_preview_enabled = true;
const char kPageLoadScriptFormat[] =
"document.open(); document.write(%s); document.close();";
@@ -89,7 +87,9 @@ void ExecuteScript(blink::WebFrame* frame,
std::string script = base::StringPrintf(script_format, json.c_str());
frame->executeScript(blink::WebString(base::UTF8ToUTF16(script)));
}
-#endif // !defined(ENABLE_PRINT_PREVIEW)
+#else
+bool g_is_preview_enabled = false;
+#endif // defined(ENABLE_PRINT_PREVIEW)
int GetDPI(const PrintMsg_Print_Params* print_params) {
#if defined(OS_MACOSX)
@@ -285,13 +285,13 @@ void ComputeWebKitPrintParamsInDesiredDpi(
print_params.page_size.height(), dpi, print_params.desired_dpi);
}
-blink::WebPlugin* GetPlugin(const blink::WebFrame* frame) {
+blink::WebPlugin* GetPlugin(const blink::WebLocalFrame* frame) {
return frame->document().isPluginDocument()
? frame->document().to<blink::WebPluginDocument>().plugin()
: NULL;
}
-bool PrintingNodeOrPdfFrame(const blink::WebFrame* frame,
+bool PrintingNodeOrPdfFrame(const blink::WebLocalFrame* frame,
const blink::WebNode& node) {
if (!node.isNull())
return true;
@@ -520,9 +520,7 @@ void PrintWebViewHelper::PrintHeaderAndFooter(
options->SetString("pageNumber",
base::StringPrintf("%d/%d", page_number, total_pages));
- // Fallback to initiator URL and title if it's empty for printed frame.
- base::string16 url = source_frame.document().url().string();
- options->SetString("url", url.empty() ? params.url : url);
+ options->SetString("url", params.url);
base::string16 title = source_frame.document().title();
options->SetString("title", title.empty() ? params.title : title);
@@ -562,7 +560,7 @@ class PrepareFrameAndViewForPrint : public blink::WebViewClient,
blink::WebLocalFrame* frame,
const blink::WebNode& node,
bool ignore_css_margins);
- virtual ~PrepareFrameAndViewForPrint();
+ ~PrepareFrameAndViewForPrint() override;
// Optional. Replaces |frame_| with selection if needed. Will call |on_ready|
// when completed.
@@ -585,24 +583,21 @@ class PrepareFrameAndViewForPrint : public blink::WebViewClient,
return owns_web_view_ && frame() && frame()->isLoading();
}
+ private:
+ // blink::WebViewClient:
+ void didStopLoading() override;
// TODO(ojan): Remove this override and have this class use a non-null
// layerTreeView.
- // blink::WebViewClient override:
- virtual bool allowsBrokenNullLayerTreeView() const;
+ bool allowsBrokenNullLayerTreeView() const override;
- protected:
- // blink::WebViewClient override:
- virtual void didStopLoading();
-
- // blink::WebFrameClient override:
- virtual blink::WebFrame* createChildFrame(
+ // blink::WebFrameClient:
+ blink::WebFrame* createChildFrame(
blink::WebLocalFrame* parent,
blink::WebTreeScopeType scope,
const blink::WebString& name,
- blink::WebSandboxFlags sandboxFlags);
- virtual void frameDetached(blink::WebFrame* frame, DetachType type);
+ blink::WebSandboxFlags sandboxFlags) override;
+ void frameDetached(blink::WebFrame* frame, DetachType type) override;
- private:
void CallOnReady();
void ResizeForPrinting();
void RestoreSize();
@@ -712,7 +707,6 @@ void PrepareFrameAndViewForPrint::CopySelection(
// on the page).
WebPreferences prefs = preferences;
prefs.javascript_enabled = false;
- prefs.java_enabled = false;
blink::WebView* web_view = blink::WebView::create(this);
owns_web_view_ = true;
@@ -826,7 +820,7 @@ PrintWebViewHelper::~PrintWebViewHelper() {
// static
void PrintWebViewHelper::DisablePreview() {
- g_is_preview_enabled_ = false;
+ g_is_preview_enabled = false;
}
bool PrintWebViewHelper::IsScriptInitiatedPrintAllowed(blink::WebFrame* frame,
@@ -839,7 +833,7 @@ bool PrintWebViewHelper::IsScriptInitiatedPrintAllowed(blink::WebFrame* frame,
// is app modal). If the print was initiated through user action, don't
// throttle. Or, if the command line flag to skip throttling has been set.
return !is_scripted_printing_blocked_ &&
- (user_initiated || g_is_preview_enabled_ ||
+ (user_initiated || g_is_preview_enabled ||
scripting_throttler_.IsAllowed(frame));
}
@@ -870,7 +864,7 @@ void PrintWebViewHelper::PrintPage(blink::WebLocalFrame* frame,
if (delegate_->OverridePrint(frame))
return;
- if (!g_is_preview_enabled_) {
+ if (!g_is_preview_enabled) {
Print(frame, blink::WebNode(), true);
} else {
print_preview_context_.InitWithFrame(frame);
@@ -1206,27 +1200,25 @@ bool PrintWebViewHelper::FinalizePrintReadyDocument() {
DCHECK(!is_print_ready_metafile_sent_);
print_preview_context_.FinalizePrintReadyDocument();
- // Get the size of the resulting metafile.
PdfMetafileSkia* metafile = print_preview_context_.metafile();
- uint32 buf_size = metafile->GetDataSize();
- DCHECK_GT(buf_size, 0u);
-
PrintHostMsg_DidPreviewDocument_Params preview_params;
- preview_params.data_size = buf_size;
- preview_params.document_cookie = print_pages_params_->params.document_cookie;
- preview_params.expected_pages_count =
- print_preview_context_.total_page_count();
- preview_params.modifiable = print_preview_context_.IsModifiable();
- preview_params.preview_request_id =
- print_pages_params_->params.preview_request_id;
// Ask the browser to create the shared memory for us.
- if (!CopyMetafileDataToSharedMem(metafile,
+ if (!CopyMetafileDataToSharedMem(*metafile,
&(preview_params.metafile_data_handle))) {
LOG(ERROR) << "CopyMetafileDataToSharedMem failed";
print_preview_context_.set_error(PREVIEW_ERROR_METAFILE_COPY_FAILED);
return false;
}
+
+ preview_params.data_size = metafile->GetDataSize();
+ preview_params.document_cookie = print_pages_params_->params.document_cookie;
+ preview_params.expected_pages_count =
+ print_preview_context_.total_page_count();
+ preview_params.modifiable = print_preview_context_.IsModifiable();
+ preview_params.preview_request_id =
+ print_pages_params_->params.preview_request_id;
+
is_print_ready_metafile_sent_ = true;
Send(new PrintHostMsg_MetafileReadyForPrinting(routing_id(), preview_params));
@@ -1287,7 +1279,7 @@ void PrintWebViewHelper::PrintNode(const blink::WebNode& node) {
// Make a copy of the node, in case RenderView::OnContextMenuClosed resets
// its |context_menu_node_|.
- if (!g_is_preview_enabled_) {
+ if (!g_is_preview_enabled) {
blink::WebNode duplicate_node(node);
Print(duplicate_node.document().frame(), duplicate_node, false);
} else {
@@ -1393,17 +1385,17 @@ void PrintWebViewHelper::PrintPages() {
Send(new PrintHostMsg_DidGetPrintedPagesCount(routing_id(),
print_params.document_cookie,
page_count));
-#endif // !defined(OS_CHROMEOS)
+#endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
if (print_params.preview_ui_id < 0) {
// Printing for system dialog.
int printed_count = params.pages.empty() ? page_count : params.pages.size();
-#if !defined(OS_CHROMEOS)
- UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.SystemDialog", printed_count);
-#else
+#if defined(OS_CHROMEOS)
UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.PrintToCloudPrintWebDialog",
printed_count);
-#endif // !defined(OS_CHROMEOS)
+#else
+ UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.SystemDialog", printed_count);
+#endif // defined(OS_CHROMEOS)
}
if (!PrintPagesNative(prep_frame_view_->frame(), page_count)) {
@@ -1665,22 +1657,25 @@ bool PrintWebViewHelper::RenderPagesForPrint(blink::WebLocalFrame* frame,
#if defined(OS_POSIX)
bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
- PdfMetafileSkia* metafile,
+ const PdfMetafileSkia& metafile,
base::SharedMemoryHandle* shared_mem_handle) {
- uint32 buf_size = metafile->GetDataSize();
+ uint32_t buf_size = metafile.GetDataSize();
+ if (buf_size == 0)
+ return false;
+
scoped_ptr<base::SharedMemory> shared_buf(
- content::RenderThread::Get()
- ->HostAllocateSharedMemoryBuffer(buf_size)
- .release());
-
- if (shared_buf) {
- if (shared_buf->Map(buf_size)) {
- metafile->GetData(shared_buf->memory(), buf_size);
- return shared_buf->GiveToProcess(base::GetCurrentProcessHandle(),
- shared_mem_handle);
- }
- }
- return false;
+ content::RenderThread::Get()->HostAllocateSharedMemoryBuffer(buf_size));
+ if (!shared_buf)
+ return false;
+
+ if (!shared_buf->Map(buf_size))
+ return false;
+
+ if (!metafile.GetData(shared_buf->memory(), buf_size))
+ return false;
+
+ return shared_buf->GiveToProcess(base::GetCurrentProcessHandle(),
+ shared_mem_handle);
}
#endif // defined(OS_POSIX)
@@ -1797,15 +1792,13 @@ bool PrintWebViewHelper::PreviewPageRendered(int page_number,
PrintHostMsg_DidPreviewPage_Params preview_page_params;
// Get the size of the resulting metafile.
- uint32 buf_size = metafile->GetDataSize();
- DCHECK_GT(buf_size, 0u);
if (!CopyMetafileDataToSharedMem(
- metafile, &(preview_page_params.metafile_data_handle))) {
+ *metafile, &(preview_page_params.metafile_data_handle))) {
LOG(ERROR) << "CopyMetafileDataToSharedMem failed";
print_preview_context_.set_error(PREVIEW_ERROR_METAFILE_COPY_FAILED);
return false;
}
- preview_page_params.data_size = buf_size;
+ preview_page_params.data_size = metafile->GetDataSize();
preview_page_params.page_number = page_number;
preview_page_params.preview_request_id =
print_pages_params_->params.preview_request_id;
diff --git a/chromium/components/printing/renderer/print_web_view_helper.h b/chromium/components/printing/renderer/print_web_view_helper.h
index 54179ffb87d..d9ea441e2aa 100644
--- a/chromium/components/printing/renderer/print_web_view_helper.h
+++ b/chromium/components/printing/renderer/print_web_view_helper.h
@@ -297,7 +297,7 @@ class PrintWebViewHelper
// Helper methods -----------------------------------------------------------
- bool CopyMetafileDataToSharedMem(PdfMetafileSkia* metafile,
+ bool CopyMetafileDataToSharedMem(const PdfMetafileSkia& metafile,
base::SharedMemoryHandle* shared_mem_handle);
// Helper method to get page layout in points and fit to page if needed.
diff --git a/chromium/components/printing/renderer/print_web_view_helper_linux.cc b/chromium/components/printing/renderer/print_web_view_helper_linux.cc
index 61a1a1d72e8..52f92ec78d1 100644
--- a/chromium/components/printing/renderer/print_web_view_helper_linux.cc
+++ b/chromium/components/printing/renderer/print_web_view_helper_linux.cc
@@ -91,10 +91,6 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame,
metafile.FinishDocument();
- // Get the size of the resulting metafile.
- uint32 buf_size = metafile.GetDataSize();
- DCHECK_GT(buf_size, 0u);
-
#if defined(OS_CHROMEOS)
NOTREACHED();
return false;
@@ -115,29 +111,15 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame,
return true;
#else
PrintHostMsg_DidPrintPage_Params printed_page_params;
- printed_page_params.data_size = 0;
- printed_page_params.document_cookie = params.params.document_cookie;
-
- {
- scoped_ptr<base::SharedMemory> shared_mem(
- content::RenderThread::Get()
- ->HostAllocateSharedMemoryBuffer(buf_size)
- .release());
- if (!shared_mem.get()) {
- NOTREACHED() << "AllocateSharedMemoryBuffer failed";
- return false;
- }
- if (!shared_mem->Map(buf_size)) {
- NOTREACHED() << "Map failed";
- return false;
- }
- metafile.GetData(shared_mem->memory(), buf_size);
- printed_page_params.data_size = buf_size;
- shared_mem->GiveToProcess(base::GetCurrentProcessHandle(),
- &(printed_page_params.metafile_data_handle));
+ if (!CopyMetafileDataToSharedMem(
+ metafile, &printed_page_params.metafile_data_handle)) {
+ return false;
}
+ printed_page_params.data_size = metafile.GetDataSize();
+ printed_page_params.document_cookie = params.params.document_cookie;
+
for (size_t i = 0; i < printed_pages.size(); ++i) {
printed_page_params.page_number = printed_pages[i];
Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params));
diff --git a/chromium/components/printing/renderer/print_web_view_helper_mac.mm b/chromium/components/printing/renderer/print_web_view_helper_mac.mm
index 7aa503c8f5d..f2b94e754a8 100644
--- a/chromium/components/printing/renderer/print_web_view_helper_mac.mm
+++ b/chromium/components/printing/renderer/print_web_view_helper_mac.mm
@@ -42,8 +42,9 @@ void PrintWebViewHelper::PrintPageInternal(
page_params.content_area = content_area_in_dpi;
// Ask the browser to create the shared memory for us.
- if (!CopyMetafileDataToSharedMem(&metafile,
+ if (!CopyMetafileDataToSharedMem(metafile,
&(page_params.metafile_data_handle))) {
+ // TODO(thestig): Fail and return false instead.
page_params.data_size = 0;
}
diff --git a/chromium/components/printing/renderer/print_web_view_helper_pdf_win.cc b/chromium/components/printing/renderer/print_web_view_helper_pdf_win.cc
index a121448bc43..56acc7484d2 100644
--- a/chromium/components/printing/renderer/print_web_view_helper_pdf_win.cc
+++ b/chromium/components/printing/renderer/print_web_view_helper_pdf_win.cc
@@ -94,47 +94,24 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame,
metafile.FinishDocument();
- // Get the size of the resulting metafile.
- uint32 buf_size = metafile.GetDataSize();
- DCHECK_GT(buf_size, 0u);
-
PrintHostMsg_DidPrintPage_Params printed_page_params;
- printed_page_params.data_size = 0;
+ if (!CopyMetafileDataToSharedMem(
+ metafile, &printed_page_params.metafile_data_handle)) {
+ return false;
+ }
+
+ printed_page_params.content_area = params.params.printable_area;
+ printed_page_params.data_size = metafile.GetDataSize();
printed_page_params.document_cookie = params.params.document_cookie;
printed_page_params.page_size = params.params.page_size;
- printed_page_params.content_area = params.params.printable_area;
-
- {
- base::SharedMemory shared_buf;
- // Allocate a shared memory buffer to hold the generated metafile data.
- if (!shared_buf.CreateAndMapAnonymous(buf_size)) {
- NOTREACHED() << "Buffer allocation failed";
- return false;
- }
-
- // Copy the bits into shared memory.
- if (!metafile.GetData(shared_buf.memory(), buf_size)) {
- NOTREACHED() << "GetData() failed";
- shared_buf.Unmap();
- return false;
- }
- shared_buf.GiveToProcess(base::GetCurrentProcessHandle(),
- &printed_page_params.metafile_data_handle);
- shared_buf.Unmap();
-
- printed_page_params.data_size = buf_size;
- Send(new PrintHostMsg_DuplicateSection(
- routing_id(),
- printed_page_params.metafile_data_handle,
- &printed_page_params.metafile_data_handle));
- }
for (size_t i = 0; i < printed_pages.size(); ++i) {
printed_page_params.page_number = printed_pages[i];
printed_page_params.page_size = page_size_in_dpi[i];
printed_page_params.content_area = content_area_in_dpi[i];
Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params));
- printed_page_params.metafile_data_handle = INVALID_HANDLE_VALUE;
+ // Send the rest of the pages with an invalid metafile handle.
+ printed_page_params.metafile_data_handle = base::SharedMemoryHandle();
}
return true;
}
@@ -204,24 +181,25 @@ void PrintWebViewHelper::PrintPageInternal(
}
bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
- PdfMetafileSkia* metafile,
+ const PdfMetafileSkia& metafile,
base::SharedMemoryHandle* shared_mem_handle) {
- uint32 buf_size = metafile->GetDataSize();
+ uint32_t buf_size = metafile.GetDataSize();
+ if (buf_size == 0)
+ return false;
+
base::SharedMemory shared_buf;
// Allocate a shared memory buffer to hold the generated metafile data.
- if (!shared_buf.CreateAndMapAnonymous(buf_size)) {
- NOTREACHED() << "Buffer allocation failed";
+ if (!shared_buf.CreateAndMapAnonymous(buf_size))
return false;
- }
// Copy the bits into shared memory.
- if (!metafile->GetData(shared_buf.memory(), buf_size)) {
- NOTREACHED() << "GetData() failed";
- shared_buf.Unmap();
+ if (!metafile.GetData(shared_buf.memory(), buf_size))
+ return false;
+
+ if (!shared_buf.GiveToProcess(base::GetCurrentProcessHandle(),
+ shared_mem_handle)) {
return false;
}
- shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle);
- shared_buf.Unmap();
Send(new PrintHostMsg_DuplicateSection(routing_id(), *shared_mem_handle,
shared_mem_handle));
diff --git a/chromium/components/proximity_auth.gypi b/chromium/components/proximity_auth.gypi
index b26f304174f..0c3fcd6d476 100644
--- a/chromium/components/proximity_auth.gypi
+++ b/chromium/components/proximity_auth.gypi
@@ -14,6 +14,7 @@
],
'dependencies': [
':cryptauth',
+ ':cryptauth_proto',
':proximity_auth_logging',
'../base/base.gyp:base',
'../base/base.gyp:base_prefs',
@@ -21,6 +22,7 @@
'../net/net.gyp:net',
],
'sources': [
+ "proximity_auth/authenticator.h",
"proximity_auth/ble/bluetooth_low_energy_characteristics_finder.cc",
"proximity_auth/ble/bluetooth_low_energy_characteristics_finder.h",
"proximity_auth/ble/bluetooth_low_energy_connection.cc",
@@ -46,24 +48,42 @@
"proximity_auth/bluetooth_util.cc",
"proximity_auth/bluetooth_util.h",
"proximity_auth/bluetooth_util_chromeos.cc",
- "proximity_auth/client.h",
- "proximity_auth/client_impl.cc",
- "proximity_auth/client_impl.h",
- "proximity_auth/client_observer.h",
+ "proximity_auth/cryptauth_enroller_factory_impl.cc",
+ "proximity_auth/cryptauth_enroller_factory_impl.h",
"proximity_auth/connection.cc",
"proximity_auth/connection.h",
"proximity_auth/connection_finder.h",
"proximity_auth/connection_observer.h",
+ "proximity_auth/device_to_device_authenticator.cc",
+ "proximity_auth/device_to_device_authenticator.h",
+ "proximity_auth/device_to_device_initiator_operations.cc",
+ "proximity_auth/device_to_device_initiator_operations.h",
+ "proximity_auth/device_to_device_secure_context.cc",
+ "proximity_auth/device_to_device_secure_context.h",
+ "proximity_auth/messenger.h",
+ "proximity_auth/messenger_impl.cc",
+ "proximity_auth/messenger_impl.h",
+ "proximity_auth/messenger_observer.h",
"proximity_auth/metrics.cc",
"proximity_auth/metrics.h",
"proximity_auth/proximity_auth_client.h",
+ "proximity_auth/proximity_auth_pref_manager.cc",
+ "proximity_auth/proximity_auth_pref_manager.h",
+ "proximity_auth/proximity_auth_pref_names.cc",
+ "proximity_auth/proximity_auth_pref_names.h",
"proximity_auth/proximity_auth_system.cc",
"proximity_auth/proximity_auth_system.h",
"proximity_auth/proximity_monitor.h",
"proximity_auth/proximity_monitor_impl.cc",
"proximity_auth/proximity_monitor_impl.h",
"proximity_auth/proximity_monitor_observer.h",
+ "proximity_auth/remote_device.cc",
"proximity_auth/remote_device.h",
+ "proximity_auth/remote_device_loader.cc",
+ "proximity_auth/remote_device_loader.h",
+ "proximity_auth/remote_device_life_cycle.h",
+ "proximity_auth/remote_device_life_cycle_impl.h",
+ "proximity_auth/remote_device_life_cycle_impl.cc",
"proximity_auth/remote_status_update.cc",
"proximity_auth/remote_status_update.h",
"proximity_auth/screenlock_bridge.cc",
@@ -74,9 +94,37 @@
"proximity_auth/switches.h",
"proximity_auth/throttled_bluetooth_connection_finder.cc",
"proximity_auth/throttled_bluetooth_connection_finder.h",
+ "proximity_auth/unlock_manager.cc",
+ "proximity_auth/unlock_manager.h",
"proximity_auth/wire_message.cc",
"proximity_auth/wire_message.h",
],
+
+ 'export_dependent_settings': [
+ 'cryptauth_proto',
+ ],
+ },
+ {
+ 'target_name': 'proximity_auth_test_support',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ ':cryptauth_test_support',
+ '../base/base.gyp:base',
+ '../testing/gmock.gyp:gmock',
+ ],
+ 'sources': [
+ "proximity_auth/device_to_device_responder_operations.cc",
+ "proximity_auth/device_to_device_responder_operations.h",
+ "proximity_auth/fake_connection.cc",
+ "proximity_auth/fake_connection.h",
+ "proximity_auth/mock_proximity_auth_client.cc",
+ "proximity_auth/mock_proximity_auth_client.h",
+ "proximity_auth/proximity_auth_test_util.cc",
+ "proximity_auth/proximity_auth_test_util.h",
+ ],
},
{
# GN version: //components/proximity_auth/logging
@@ -119,6 +167,7 @@
'cryptauth_proto',
'../base/base.gyp:base',
'../crypto/crypto.gyp:crypto',
+ '../components/components.gyp:gcm_driver',
'../google_apis/google_apis.gyp:google_apis',
'../net/net.gyp:net',
],
@@ -141,6 +190,10 @@
"proximity_auth/cryptauth/cryptauth_enrollment_manager.cc",
"proximity_auth/cryptauth/cryptauth_enrollment_manager.h",
"proximity_auth/cryptauth/cryptauth_enrollment_utils.cc",
+ "proximity_auth/cryptauth/cryptauth_gcm_manager.cc",
+ "proximity_auth/cryptauth/cryptauth_gcm_manager.h",
+ "proximity_auth/cryptauth/cryptauth_gcm_manager_impl.cc",
+ "proximity_auth/cryptauth/cryptauth_gcm_manager_impl.h",
"proximity_auth/cryptauth/pref_names.cc",
"proximity_auth/cryptauth/pref_names.h",
"proximity_auth/cryptauth/secure_message_delegate.cc",
@@ -166,6 +219,8 @@
'../testing/gmock.gyp:gmock',
],
'sources': [
+ "proximity_auth/cryptauth/fake_cryptauth_gcm_manager.cc",
+ "proximity_auth/cryptauth/fake_cryptauth_gcm_manager.h",
"proximity_auth/cryptauth/fake_secure_message_delegate.cc",
"proximity_auth/cryptauth/fake_secure_message_delegate.h",
"proximity_auth/cryptauth/mock_cryptauth_client.cc",
@@ -187,19 +242,19 @@
'../ui/resources/ui_resources.gyp:ui_resources',
'components_resources.gyp:components_resources',
'cryptauth',
+ 'cryptauth_proto',
'proximity_auth',
],
'include_dirs': [
'..',
],
'sources': [
- 'proximity_auth/webui/cryptauth_enroller_factory_impl.cc',
- 'proximity_auth/webui/cryptauth_enroller_factory_impl.h',
'proximity_auth/webui/proximity_auth_ui.cc',
'proximity_auth/webui/proximity_auth_ui.h',
- 'proximity_auth/webui/proximity_auth_ui_delegate.h',
'proximity_auth/webui/proximity_auth_webui_handler.cc',
'proximity_auth/webui/proximity_auth_webui_handler.h',
+ 'proximity_auth/webui/reachable_phone_flow.cc',
+ 'proximity_auth/webui/reachable_phone_flow.h',
'proximity_auth/webui/url_constants.cc',
'proximity_auth/webui/url_constants.h',
],
diff --git a/chromium/components/proxy_config.gypi b/chromium/components/proxy_config.gypi
index a6926f9b454..985bf117dc3 100644
--- a/chromium/components/proxy_config.gypi
+++ b/chromium/components/proxy_config.gypi
@@ -10,18 +10,29 @@
'type': '<(component)',
'dependencies': [
'../base/base.gyp:base',
+ '../base/base.gyp:base_prefs',
'../net/net.gyp:net',
+ '../url/url.gyp:url_lib',
+ 'pref_registry',
],
'include_dirs': [
'..',
],
+ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+ 'msvs_disabled_warnings': [ 4267, ],
'defines': [
'PROXY_CONFIG_IMPLEMENTATION',
],
'sources': [
+ 'proxy_config/pref_proxy_config_tracker.cc',
+ 'proxy_config/pref_proxy_config_tracker.h',
+ 'proxy_config/pref_proxy_config_tracker_impl.cc',
+ 'proxy_config/pref_proxy_config_tracker_impl.h',
'proxy_config/proxy_config_dictionary.cc',
'proxy_config/proxy_config_dictionary.h',
'proxy_config/proxy_config_export.h',
+ 'proxy_config/proxy_config_pref_names.cc',
+ 'proxy_config/proxy_config_pref_names.h',
'proxy_config/proxy_prefs.cc',
'proxy_config/proxy_prefs.h',
],
diff --git a/chromium/components/rappor.gypi b/chromium/components/rappor.gypi
index 88c77f0c5e0..8dd2dcf3641 100644
--- a/chromium/components/rappor.gypi
+++ b/chromium/components/rappor.gypi
@@ -16,6 +16,7 @@
'../crypto/crypto.gyp:crypto',
'../net/net.gyp:net',
'../third_party/smhasher/smhasher.gyp:cityhash',
+ 'data_use_measurement_core',
'metrics',
'variations',
],
diff --git a/chromium/components/resources/BUILD.gn b/chromium/components/resources/BUILD.gn
index 6f68f8f63b9..388751cf0ba 100644
--- a/chromium/components/resources/BUILD.gn
+++ b/chromium/components/resources/BUILD.gn
@@ -4,9 +4,11 @@
import("//tools/grit/grit_rule.gni")
+about_credits_file = "$target_gen_dir/about_credits.html"
+
# GYP version: components/components_resources.gyp:components_resources
group("resources") {
- deps = [
+ public_deps = [
":components_resources",
":components_scaled_resources",
]
@@ -24,6 +26,15 @@ grit("components_resources") {
"components_resources.pak",
]
output_dir = "$root_gen_dir/components"
+
+ grit_flags = [
+ "-E",
+ "about_credits_file=" + rebase_path(about_credits_file, root_build_dir),
+ ]
+
+ deps = [
+ ":about_credits",
+ ]
}
# GYP version: components/components_resources.gyp
@@ -38,6 +49,31 @@ grit("components_scaled_resources") {
"components_resources_100_percent.pak",
"components_resources_200_percent.pak",
"components_resources_300_percent.pak",
+ "components_resources_material_100_percent.pak",
+ "components_resources_material_200_percent.pak",
]
output_dir = "$root_gen_dir/components"
}
+
+# GYP version: components/components_resources.gyp:about_credits
+action("about_credits") {
+ script = "//tools/licenses.py"
+
+ inputs = [
+ # This is not a complete list. TODO(phajdan.jr, dbeam): licenses.py needs to
+ # generate a .d file with all the licenses/credits that about:credits uses.
+ # Then about:credits will automatically rebuild when one of them changes.
+ # See: depfile in gn's documentation (gn help depfile).
+ "../about_ui/resources/about_credits.tmpl",
+ "../about_ui/resources/about_credits_entry.tmpl",
+ ]
+
+ outputs = [
+ about_credits_file,
+ ]
+
+ args = [
+ "credits",
+ rebase_path(about_credits_file, root_build_dir),
+ ]
+}
diff --git a/chromium/components/resources/OWNERS b/chromium/components/resources/OWNERS
index 6b2a1804ab3..d38c0de8f2b 100644
--- a/chromium/components/resources/OWNERS
+++ b/chromium/components/resources/OWNERS
@@ -1,7 +1,8 @@
+per-file autofill_scaled_resources.grdp=estade@chromium.org
per-file data_reduction_proxy*=bengr@chromium.org
per-file data_reduction_proxy*=sclittle@chromium.org
-per-file dom_distiller*=cjhopman@chromium.org
+per-file data_reduction_proxy*=megjablon@chromium.org
+per-file dom_distiller*=mdjones@chromium.org
per-file dom_distiller*=nyquist@chromium.org
per-file proximity_auth*=isherman@chromium.org
per-file proximity_auth*=tengs@chromium.org
-per-file webui_generator_resources.grdp=dzhioev@chromium.org
diff --git a/chromium/components/resources/about_ui_resources.grdp b/chromium/components/resources/about_ui_resources.grdp
new file mode 100644
index 00000000000..28f16fcfaef
--- /dev/null
+++ b/chromium/components/resources/about_ui_resources.grdp
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <include name="IDR_ABOUT_UI_CREDITS_HTML" file="${about_credits_file}" use_base_dir="false" type="BINDATA" />
+ <include name="IDR_ABOUT_UI_CREDITS_JS" file="../about_ui/resources/about_credits.js" type="BINDATA" />
+</grit-part>
diff --git a/chromium/components/resources/autofill_scaled_resources.grdp b/chromium/components/resources/autofill_scaled_resources.grdp
index b419e82d539..ec1db8a14cb 100644
--- a/chromium/components/resources/autofill_scaled_resources.grdp
+++ b/chromium/components/resources/autofill_scaled_resources.grdp
@@ -5,9 +5,16 @@
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_GENERIC" file="autofill/cc-generic.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_MASTERCARD" file="autofill/mastercard.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_VISA" file="autofill/visa.png" />
- <!-- This is not used on desktop, only Android, so use a placeholder file. -->
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_SCAN_NEW" file="autofill/cc-generic.png" />
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_MAC_CONTACTS_ICON" file="autofill/mac_contacts_icon.png" />
+
+ <if expr="is_android">
+ <!-- These are not used on desktop, only Android, so use a placeholder file.
+ TODO(rouslan): Remove non-keyboard-accessory icon when keyboard
+ accessory becomes default on Android. -->
+ <structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_SCAN_NEW" file="autofill/cc-generic.png" />
+ <structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_SCAN_NEW_KEYBOARD_ACCESSORY" file="autofill/cc-generic.png" />
+ <structure type="chrome_scaled_image" name="IDR_AUTOFILL_SETTINGS" file="autofill/cc-generic.png" />
+ </if>
+
<structure type="chrome_scaled_image" name="IDR_CREDIT_CARD_CVC_HINT" file="autofill/credit_card_cvc_hint.png" />
<structure type="chrome_scaled_image" name="IDR_CREDIT_CARD_CVC_HINT_AMEX" file="autofill/credit_card_cvc_hint_amex.png" />
<structure type="chrome_scaled_image" name="IDR_INFOBAR_AUTOFILL_CC" file="autofill/infobar_autofill_cc.png" />
diff --git a/chromium/components/resources/components_resources.grd b/chromium/components/resources/components_resources.grd
index 289e266cd29..a4676e3e4f6 100644
--- a/chromium/components/resources/components_resources.grd
+++ b/chromium/components/resources/components_resources.grd
@@ -8,10 +8,16 @@
</outputs>
<release seq="1">
<includes>
+ <part file="about_ui_resources.grdp" />
<part file="data_reduction_proxy_resources.grdp" />
<part file="dom_distiller_resources.grdp" />
+ <part file="flags_ui_resources.grdp" />
+ <part file="gcm_driver_resources.grdp" />
+ <part file="net_log_resources.grdp" />
<part file="printing_resources.grdp" />
<part file="proximity_auth_resources.grdp" />
+ <part file="security_interstitials_resources.grdp" />
+ <part file="sync_driver_resources.grdp" />
<part file="translate_resources.grdp" />
</includes>
</release>
diff --git a/chromium/components/resources/components_scaled_resources.grd b/chromium/components/resources/components_scaled_resources.grd
index 7e58ee00fa8..fcb9a367f2c 100644
--- a/chromium/components/resources/components_scaled_resources.grd
+++ b/chromium/components/resources/components_scaled_resources.grd
@@ -7,6 +7,8 @@
<output filename="components_resources_100_percent.pak" type="data_package" context="default_100_percent" />
<output filename="components_resources_200_percent.pak" type="data_package" context="default_200_percent" />
<output filename="components_resources_300_percent.pak" type="data_package" context="default_300_percent" />
+ <output filename="components_resources_material_100_percent.pak" type="data_package" context="material_100_percent" fallback_to_default_layout="false" />
+ <output filename="components_resources_material_200_percent.pak" type="data_package" context="material_200_percent" fallback_to_default_layout="false" />
</outputs>
<release seq="1">
<structures fallback_to_low_resolution="true">
diff --git a/chromium/components/resources/default_100_percent/autofill/mac_contacts_icon.png b/chromium/components/resources/default_100_percent/autofill/mac_contacts_icon.png
deleted file mode 100644
index 4e4b06517da..00000000000
--- a/chromium/components/resources/default_100_percent/autofill/mac_contacts_icon.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/omnibox/ios/location_bar_http.png b/chromium/components/resources/default_100_percent/omnibox/ios/location_bar_http.png
new file mode 100644
index 00000000000..46a2b64d403
--- /dev/null
+++ b/chromium/components/resources/default_100_percent/omnibox/ios/location_bar_http.png
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/omnibox/location_bar_http.png b/chromium/components/resources/default_100_percent/omnibox/location_bar_http.png
new file mode 100644
index 00000000000..dd2cf041957
--- /dev/null
+++ b/chromium/components/resources/default_100_percent/omnibox/location_bar_http.png
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/mac_contacts_icon.png b/chromium/components/resources/default_200_percent/autofill/mac_contacts_icon.png
deleted file mode 100644
index 7dcb94cbd63..00000000000
--- a/chromium/components/resources/default_200_percent/autofill/mac_contacts_icon.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/omnibox/ios/location_bar_http.png b/chromium/components/resources/default_200_percent/omnibox/ios/location_bar_http.png
new file mode 100644
index 00000000000..da5ee69ea17
--- /dev/null
+++ b/chromium/components/resources/default_200_percent/omnibox/ios/location_bar_http.png
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/omnibox/location_bar_http.png b/chromium/components/resources/default_200_percent/omnibox/location_bar_http.png
new file mode 100644
index 00000000000..12935710699
--- /dev/null
+++ b/chromium/components/resources/default_200_percent/omnibox/location_bar_http.png
Binary files differ
diff --git a/chromium/components/resources/default_300_percent/omnibox/ios/location_bar_http.png b/chromium/components/resources/default_300_percent/omnibox/ios/location_bar_http.png
new file mode 100644
index 00000000000..bb5a541840d
--- /dev/null
+++ b/chromium/components/resources/default_300_percent/omnibox/ios/location_bar_http.png
Binary files differ
diff --git a/chromium/components/resources/flags_ui_resources.grdp b/chromium/components/resources/flags_ui_resources.grdp
new file mode 100644
index 00000000000..f5e599c8fa7
--- /dev/null
+++ b/chromium/components/resources/flags_ui_resources.grdp
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <include name="IDR_FLAGS_UI_FLAGS_HTML" file="../flags_ui/resources/flags.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_FLAGS_UI_FLAGS_JS" file="../flags_ui/resources/flags.js" type="BINDATA" />
+</grit-part>
diff --git a/chromium/components/resources/gcm_driver_resources.grdp b/chromium/components/resources/gcm_driver_resources.grdp
new file mode 100644
index 00000000000..7f89c306ce5
--- /dev/null
+++ b/chromium/components/resources/gcm_driver_resources.grdp
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <include name="IDR_GCM_DRIVER_GCM_INTERNALS_HTML" file="../gcm_driver/resources/gcm_internals.html" type="BINDATA" />
+ <include name="IDR_GCM_DRIVER_GCM_INTERNALS_CSS" file="../gcm_driver/resources/gcm_internals.css" type="BINDATA" />
+ <include name="IDR_GCM_DRIVER_GCM_INTERNALS_JS" file="../gcm_driver/resources/gcm_internals.js" type="BINDATA" />
+</grit-part>
diff --git a/chromium/components/resources/material_100_percent/omnibox/location_bar_http.png b/chromium/components/resources/material_100_percent/omnibox/location_bar_http.png
new file mode 100644
index 00000000000..6588aef7657
--- /dev/null
+++ b/chromium/components/resources/material_100_percent/omnibox/location_bar_http.png
Binary files differ
diff --git a/chromium/components/resources/material_100_percent/omnibox/omnibox_extension_app.png b/chromium/components/resources/material_100_percent/omnibox/omnibox_extension_app.png
new file mode 100644
index 00000000000..0ac642c7a35
--- /dev/null
+++ b/chromium/components/resources/material_100_percent/omnibox/omnibox_extension_app.png
Binary files differ
diff --git a/chromium/components/resources/material_100_percent/omnibox/omnibox_http.png b/chromium/components/resources/material_100_percent/omnibox/omnibox_http.png
new file mode 100644
index 00000000000..6588aef7657
--- /dev/null
+++ b/chromium/components/resources/material_100_percent/omnibox/omnibox_http.png
Binary files differ
diff --git a/chromium/components/resources/material_100_percent/omnibox/omnibox_search.png b/chromium/components/resources/material_100_percent/omnibox/omnibox_search.png
new file mode 100644
index 00000000000..af25879a23b
--- /dev/null
+++ b/chromium/components/resources/material_100_percent/omnibox/omnibox_search.png
Binary files differ
diff --git a/chromium/components/resources/material_200_percent/omnibox/location_bar_http.png b/chromium/components/resources/material_200_percent/omnibox/location_bar_http.png
new file mode 100644
index 00000000000..d6e92192a2f
--- /dev/null
+++ b/chromium/components/resources/material_200_percent/omnibox/location_bar_http.png
Binary files differ
diff --git a/chromium/components/resources/material_200_percent/omnibox/omnibox_extension_app.png b/chromium/components/resources/material_200_percent/omnibox/omnibox_extension_app.png
new file mode 100644
index 00000000000..865be9368da
--- /dev/null
+++ b/chromium/components/resources/material_200_percent/omnibox/omnibox_extension_app.png
Binary files differ
diff --git a/chromium/components/resources/material_200_percent/omnibox/omnibox_http.png b/chromium/components/resources/material_200_percent/omnibox/omnibox_http.png
new file mode 100644
index 00000000000..d6e92192a2f
--- /dev/null
+++ b/chromium/components/resources/material_200_percent/omnibox/omnibox_http.png
Binary files differ
diff --git a/chromium/components/resources/material_200_percent/omnibox/omnibox_search.png b/chromium/components/resources/material_200_percent/omnibox/omnibox_search.png
new file mode 100644
index 00000000000..62ab4233389
--- /dev/null
+++ b/chromium/components/resources/material_200_percent/omnibox/omnibox_search.png
Binary files differ
diff --git a/chromium/components/resources/net_log_resources.grdp b/chromium/components/resources/net_log_resources.grdp
new file mode 100644
index 00000000000..34e88e4d8bd
--- /dev/null
+++ b/chromium/components/resources/net_log_resources.grdp
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <include name="IDR_NET_LOG_NET_EXPORT_HTML" file="../net_log/resources/net_export.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_NET_LOG_NET_EXPORT_JS" file="../net_log/resources/net_export.js" flattenhtml="true" type="BINDATA" />
+</grit-part>
diff --git a/chromium/components/resources/omnibox_scaled_resources.grdp b/chromium/components/resources/omnibox_scaled_resources.grdp
index 901419e8874..6d34fb93e70 100644
--- a/chromium/components/resources/omnibox_scaled_resources.grdp
+++ b/chromium/components/resources/omnibox_scaled_resources.grdp
@@ -3,6 +3,7 @@
<structure type="chrome_scaled_image" name="IDR_OMNIBOX_CALCULATOR" file="omnibox/omnibox_calculator.png" />
<structure type="chrome_scaled_image" name="IDR_OMNIBOX_EXTENSION_APP" file="omnibox/omnibox_extension_app.png" />
<if expr="is_ios">
+ <structure type="chrome_scaled_image" name="IDR_LOCATION_BAR_HTTP" file="omnibox/ios/location_bar_http.png" />
<structure type="chrome_scaled_image" name="IDR_OMNIBOX_HISTORY" file="omnibox/ios/omnibox_history.png" />
<structure type="chrome_scaled_image" name="IDR_OMNIBOX_HISTORY_INCOGNITO" file="omnibox/ios/omnibox_history_incognito.png" />
<structure type="chrome_scaled_image" name="IDR_OMNIBOX_HTTP" file="omnibox/ios/omnibox_http.png" />
@@ -11,6 +12,7 @@
<structure type="chrome_scaled_image" name="IDR_OMNIBOX_SEARCH_INCOGNITO" file="omnibox/ios/omnibox_search_incognito.png" />
</if>
<if expr="not is_ios">
+ <structure type="chrome_scaled_image" name="IDR_LOCATION_BAR_HTTP" file="omnibox/location_bar_http.png" />
<structure type="chrome_scaled_image" name="IDR_OMNIBOX_HTTP" file="omnibox/omnibox_http.png" />
<structure type="chrome_scaled_image" name="IDR_OMNIBOX_SEARCH" file="omnibox/omnibox_search.png" />
</if>
diff --git a/chromium/components/resources/proximity_auth_resources.grdp b/chromium/components/resources/proximity_auth_resources.grdp
index 805f8d7077b..0c71d061452 100644
--- a/chromium/components/resources/proximity_auth_resources.grdp
+++ b/chromium/components/resources/proximity_auth_resources.grdp
@@ -26,6 +26,10 @@
file="../proximity_auth/webui/resources/eligible-devices.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_PROXIMITY_AUTH_ELIGIBLE_DEVICES_JS"
file="../proximity_auth/webui/resources/eligible-devices.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+ <include name="IDR_PROXIMITY_AUTH_REACHABLE_DEVICES_HTML"
+ file="../proximity_auth/webui/resources/reachable-devices.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+ <include name="IDR_PROXIMITY_AUTH_REACHABLE_DEVICES_JS"
+ file="../proximity_auth/webui/resources/reachable-devices.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_PROXIMITY_AUTH_CRYPTAUTH_INTERFACE_JS"
file="../proximity_auth/webui/resources/cryptauth_interface.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
</grit-part>
diff --git a/chromium/components/resources/security_interstitials_resources.grdp b/chromium/components/resources/security_interstitials_resources.grdp
new file mode 100644
index 00000000000..907ef5fe0fc
--- /dev/null
+++ b/chromium/components/resources/security_interstitials_resources.grdp
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <include name="IDR_SECURITY_INTERSTITIAL_UI_HTML" file="../security_interstitials/core/browser/resources/interstitial_ui.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_SECURITY_INTERSTITIAL_HTML" file="../security_interstitials/core/browser/resources/interstitial_v2.html" flattenhtml="true" type="BINDATA" />
+</grit-part> \ No newline at end of file
diff --git a/chromium/components/resources/sync_driver_resources.grdp b/chromium/components/resources/sync_driver_resources.grdp
new file mode 100644
index 00000000000..bb0caa33546
--- /dev/null
+++ b/chromium/components/resources/sync_driver_resources.grdp
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_HTML" file="../sync_driver/resources/index.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_JS" file="../sync_driver/resources/sync_index.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_CHROME_SYNC_JS" file="../sync_driver/resources/chrome_sync.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_TYPES_JS" file="../sync_driver/resources/types.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_LOG_JS" file="../sync_driver/resources/sync_log.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS" file="../sync_driver/resources/sync_node_browser.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_SEARCH_JS" file="../sync_driver/resources/sync_search.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_ABOUT_JS" file="../sync_driver/resources/about.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_DATA_JS" file="../sync_driver/resources/data.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_EVENTS_JS" file="../sync_driver/resources/events.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SEARCH_JS" file="../sync_driver/resources/search.js" type="BINDATA" />
+</grit-part>
diff --git a/chromium/components/rlz.gypi b/chromium/components/rlz.gypi
new file mode 100644
index 00000000000..9030258d66f
--- /dev/null
+++ b/chromium/components/rlz.gypi
@@ -0,0 +1,38 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/rlz
+ 'target_name': 'rlz',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../net/net.gyp:net',
+ '../rlz/rlz.gyp:rlz_lib',
+ 'google_core_browser',
+ ],
+ 'sources': [
+ 'rlz/rlz_tracker.cc',
+ 'rlz/rlz_tracker.h',
+ 'rlz/rlz_tracker_chromeos.cc',
+ 'rlz/rlz_tracker_delegate.h',
+ 'rlz/rlz_tracker_ios.cc',
+ 'rlz/rlz_tracker_mac.cc',
+ 'rlz/rlz_tracker_win.cc',
+ ],
+ 'conditions': [
+ ['OS == "ios"', {
+ 'dependencies': [
+ '../ui/base/ui_base.gyp:ui_base',
+ ],
+ }],
+ ],
+ },
+ ],
+}
diff --git a/chromium/components/safe_json.gypi b/chromium/components/safe_json.gypi
index dcf28244576..11ab7889f88 100644
--- a/chromium/components/safe_json.gypi
+++ b/chromium/components/safe_json.gypi
@@ -13,17 +13,37 @@
'../base/base.gyp:base',
'../components/components_strings.gyp:components_strings',
'../content/content.gyp:content_browser',
+ '../content/content.gyp:content_common',
'../ui/base/ui_base.gyp:ui_base',
],
'include_dirs': [
'..',
],
'sources': [
+ 'safe_json/android/component_jni_registrar.cc',
+ 'safe_json/android/component_jni_registrar.h',
+ 'safe_json/json_sanitizer.cc',
+ 'safe_json/json_sanitizer.h',
+ 'safe_json/json_sanitizer_android.cc',
'safe_json/safe_json_parser.cc',
'safe_json/safe_json_parser.h',
+ 'safe_json/safe_json_parser_android.cc',
+ 'safe_json/safe_json_parser_android.h',
'safe_json/safe_json_parser_impl.cc',
'safe_json/safe_json_parser_impl.h',
],
+ 'conditions': [
+ ['OS == "android"', {
+ 'dependencies': [
+ 'safe_json_jni_headers',
+ ],
+ 'sources!': [
+ 'safe_json/json_sanitizer.cc',
+ 'safe_json/safe_json_parser_impl.cc',
+ 'safe_json/safe_json_parser_impl.h',
+ ],
+ }],
+ ],
},
{
'target_name': 'safe_json_test_support',
@@ -45,7 +65,8 @@
'type': 'static_library',
'dependencies': [
'../base/base.gyp:base',
- '../content/content.gyp:content_browser',
+ '../content/content.gyp:content_common',
+ '../content/content.gyp:content_utility',
'../ipc/ipc.gyp:ipc',
],
'include_dirs': [
@@ -59,4 +80,34 @@
],
},
],
+ 'conditions': [
+ ['OS=="android"', {
+ 'targets': [
+ {
+ # GN version: //components/safe_json/android:safe_json_java
+ 'target_name': 'safe_json_java',
+ 'type': 'none',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ ],
+ 'variables': {
+ 'java_in_dir': 'safe_json/android/java',
+ },
+ 'includes': [ '../build/java.gypi' ],
+ },
+ {
+ # GN version: //components/safe_json:jni
+ 'target_name': 'safe_json_jni_headers',
+ 'type': 'none',
+ 'sources': [
+ 'safe_json/android/java/src/org/chromium/components/safejson/JsonSanitizer.java',
+ ],
+ 'variables': {
+ 'jni_gen_package': 'safe_json',
+ },
+ 'includes': [ '../build/jni_generator.gypi' ],
+ },
+ ],
+ }],
+ ]
}
diff --git a/chromium/components/scheduler/BUILD.gn b/chromium/components/scheduler/BUILD.gn
index c822116d118..2795fdbfcfd 100644
--- a/chromium/components/scheduler/BUILD.gn
+++ b/chromium/components/scheduler/BUILD.gn
@@ -16,7 +16,6 @@ component("scheduler") {
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
- ":common",
"//base",
"//cc:cc",
"//third_party/WebKit/public:blink",
@@ -28,31 +27,31 @@ component("scheduler") {
]
}
-# GYP version: components/scheduler.gypi:scheduler_common
-source_set("common") {
- sources = rebase_path(scheduler_gypi_values.scheduler_common_sources,
- ".",
- "//components/scheduler")
-}
-
source_set("unit_tests") {
testonly = true
sources = [
- "child/nestable_task_runner_for_test.cc",
- "child/nestable_task_runner_for_test.h",
- "child/prioritizing_task_queue_selector_unittest.cc",
+ "base/nestable_task_runner_for_test.cc",
+ "base/nestable_task_runner_for_test.h",
+ "base/task_queue_manager_unittest.cc",
+ "base/task_queue_selector_unittest.cc",
+ "base/task_queue_sets_unittest.cc",
+ "base/test_always_fail_time_source.cc",
+ "base/test_always_fail_time_source.h",
+ "base/test_time_source.cc",
+ "base/test_time_source.h",
+ "child/idle_helper_unittest.cc",
"child/scheduler_helper_unittest.cc",
- "child/task_queue_manager_unittest.cc",
- "child/test_time_source.cc",
- "child/test_time_source.h",
+ "child/scheduler_task_runner_delegate_for_test.cc",
+ "child/scheduler_task_runner_delegate_for_test.h",
+ "child/scheduler_task_runner_delegate_impl_unittest.cc",
"child/webthread_impl_for_worker_scheduler_unittest.cc",
"child/worker_scheduler_impl_unittest.cc",
"renderer/deadline_task_runner_unittest.cc",
"renderer/renderer_scheduler_impl_unittest.cc",
+ "renderer/task_cost_estimator_unittest.cc",
+ "renderer/user_model_unittest.cc",
"renderer/webthread_impl_for_renderer_scheduler_unittest.cc",
- "test/test_always_fail_time_source.cc",
- "test/test_always_fail_time_source.h",
]
deps = [
diff --git a/chromium/components/scheduler/DEPS b/chromium/components/scheduler/DEPS
index a298a1715c6..2d4a7445628 100644
--- a/chromium/components/scheduler/DEPS
+++ b/chromium/components/scheduler/DEPS
@@ -1,4 +1,3 @@
include_rules = [
"-components/scheduler",
- "+components/scheduler/common",
]
diff --git a/chromium/components/scheduler/base/DEPS b/chromium/components/scheduler/base/DEPS
new file mode 100644
index 00000000000..5d86a1bc60e
--- /dev/null
+++ b/chromium/components/scheduler/base/DEPS
@@ -0,0 +1,9 @@
+include_rules = [
+ "+components/scheduler/scheduler_export.h",
+]
+
+specific_include_rules = {
+ "(test_time_source|.*test)\.cc": [
+ "+cc/test",
+ ],
+}
diff --git a/chromium/components/scheduler/child/cancelable_closure_holder.cc b/chromium/components/scheduler/base/cancelable_closure_holder.cc
index 0e1660a9481..54c1462f5d3 100644
--- a/chromium/components/scheduler/child/cancelable_closure_holder.cc
+++ b/chromium/components/scheduler/base/cancelable_closure_holder.cc
@@ -2,15 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/scheduler/child/cancelable_closure_holder.h"
+#include "components/scheduler/base/cancelable_closure_holder.h"
namespace scheduler {
-CancelableClosureHolder::CancelableClosureHolder() {
-}
+CancelableClosureHolder::CancelableClosureHolder() {}
-CancelableClosureHolder::~CancelableClosureHolder() {
-}
+CancelableClosureHolder::~CancelableClosureHolder() {}
void CancelableClosureHolder::Reset(const base::Closure& callback) {
callback_ = callback;
diff --git a/chromium/components/scheduler/child/cancelable_closure_holder.h b/chromium/components/scheduler/base/cancelable_closure_holder.h
index 20968a46096..47a277e01ae 100644
--- a/chromium/components/scheduler/child/cancelable_closure_holder.h
+++ b/chromium/components/scheduler/base/cancelable_closure_holder.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_SCHEDULER_CHILD_CANCELABLE_CLOSURE_HOLDER_H_
-#define COMPONENTS_SCHEDULER_CHILD_CANCELABLE_CLOSURE_HOLDER_H_
+#ifndef COMPONENTS_SCHEDULER_BASE_CANCELABLE_CLOSURE_HOLDER_H_
+#define COMPONENTS_SCHEDULER_BASE_CANCELABLE_CLOSURE_HOLDER_H_
#include "base/cancelable_callback.h"
@@ -36,4 +36,4 @@ class CancelableClosureHolder {
} // namespace scheduler
-#endif // COMPONENTS_SCHEDULER_CHILD_CANCELABLE_CLOSURE_HOLDER_H_
+#endif // COMPONENTS_SCHEDULER_BASE_CANCELABLE_CLOSURE_HOLDER_H_
diff --git a/chromium/components/scheduler/base/lazy_now.cc b/chromium/components/scheduler/base/lazy_now.cc
new file mode 100644
index 00000000000..411e51b56f4
--- /dev/null
+++ b/chromium/components/scheduler/base/lazy_now.cc
@@ -0,0 +1,19 @@
+// 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/scheduler/base/lazy_now.h"
+
+#include "components/scheduler/base/task_queue_manager.h"
+
+namespace scheduler {
+namespace internal {
+
+base::TimeTicks LazyNow::Now() {
+ if (now_.is_null())
+ now_ = task_queue_manager_->Now();
+ return now_;
+}
+
+} // namespace internal
+} // namespace scheduler
diff --git a/chromium/components/scheduler/base/lazy_now.h b/chromium/components/scheduler/base/lazy_now.h
new file mode 100644
index 00000000000..db5f05948ea
--- /dev/null
+++ b/chromium/components/scheduler/base/lazy_now.h
@@ -0,0 +1,37 @@
+// 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_SCHEDULER_BASE_LAZY_NOW_H_
+#define COMPONENTS_SCHEDULER_BASE_LAZY_NOW_H_
+
+#include "base/time/time.h"
+
+namespace scheduler {
+class TaskQueueManager;
+
+namespace internal {
+
+// Now() is somewhat expensive so it makes sense not to call Now() unless we
+// really need to.
+class LazyNow {
+ public:
+ explicit LazyNow(base::TimeTicks now)
+ : task_queue_manager_(nullptr), now_(now) {
+ DCHECK(!now.is_null());
+ }
+
+ explicit LazyNow(TaskQueueManager* task_queue_manager)
+ : task_queue_manager_(task_queue_manager) {}
+
+ base::TimeTicks Now();
+
+ private:
+ TaskQueueManager* task_queue_manager_; // NOT OWNED
+ base::TimeTicks now_;
+};
+
+} // namespace internal
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_BASE_LAZY_NOW_H_
diff --git a/chromium/components/scheduler/child/nestable_single_thread_task_runner.h b/chromium/components/scheduler/base/nestable_single_thread_task_runner.h
index 0b507a2d254..2fc7c28f283 100644
--- a/chromium/components/scheduler/child/nestable_single_thread_task_runner.h
+++ b/chromium/components/scheduler/base/nestable_single_thread_task_runner.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_SCHEDULER_CHILD_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
-#define COMPONENTS_SCHEDULER_CHILD_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
+#ifndef COMPONENTS_SCHEDULER_BASE_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
+#define COMPONENTS_SCHEDULER_BASE_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
#include "base/single_thread_task_runner.h"
#include "base/message_loop/message_loop.h"
@@ -21,12 +21,6 @@ class SCHEDULER_EXPORT NestableSingleThreadTaskRunner
// a nested task).
virtual bool IsNested() const = 0;
- // Adds and removes MessageLoop::TaskObservers to the task runner.
- virtual void AddTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) = 0;
- virtual void RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) = 0;
-
protected:
~NestableSingleThreadTaskRunner() override {}
@@ -35,4 +29,4 @@ class SCHEDULER_EXPORT NestableSingleThreadTaskRunner
} // namespace scheduler
-#endif // COMPONENTS_SCHEDULER_CHILD_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
+#endif // COMPONENTS_SCHEDULER_BASE_NESTABLE_SINGLE_THREAD_TASK_RUNNER_H_
diff --git a/chromium/components/scheduler/base/nestable_task_runner_for_test.cc b/chromium/components/scheduler/base/nestable_task_runner_for_test.cc
new file mode 100644
index 00000000000..5f20dd4264e
--- /dev/null
+++ b/chromium/components/scheduler/base/nestable_task_runner_for_test.cc
@@ -0,0 +1,46 @@
+// 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/scheduler/base/nestable_task_runner_for_test.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+
+namespace scheduler {
+
+// static
+scoped_refptr<NestableTaskRunnerForTest> NestableTaskRunnerForTest::Create(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ return make_scoped_refptr(new NestableTaskRunnerForTest(task_runner));
+}
+
+NestableTaskRunnerForTest::NestableTaskRunnerForTest(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : task_runner_(task_runner) {}
+
+NestableTaskRunnerForTest::~NestableTaskRunnerForTest() {}
+
+bool NestableTaskRunnerForTest::PostDelayedTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) {
+ return task_runner_->PostDelayedTask(from_here, task, delay);
+}
+
+bool NestableTaskRunnerForTest::PostNonNestableDelayedTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) {
+ return task_runner_->PostNonNestableDelayedTask(from_here, task, delay);
+}
+
+bool NestableTaskRunnerForTest::RunsTasksOnCurrentThread() const {
+ return task_runner_->RunsTasksOnCurrentThread();
+}
+
+bool NestableTaskRunnerForTest::IsNested() const {
+ return false;
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/child/nestable_task_runner_for_test.h b/chromium/components/scheduler/base/nestable_task_runner_for_test.h
index 120fe0070e6..593b846a073 100644
--- a/chromium/components/scheduler/child/nestable_task_runner_for_test.h
+++ b/chromium/components/scheduler/base/nestable_task_runner_for_test.h
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_SCHEDULER_NESTABLE_TASK_RUNNER_FOR_TEST_H_
-#define CONTENT_RENDERER_SCHEDULER_NESTABLE_TASK_RUNNER_FOR_TEST_H_
+#ifndef CONTENT_RENDERER_SCHEDULER_BASE_NESTABLE_TASK_RUNNER_FOR_TEST_H_
+#define CONTENT_RENDERER_SCHEDULER_BASE_NESTABLE_TASK_RUNNER_FOR_TEST_H_
-#include "components/scheduler/child/nestable_single_thread_task_runner.h"
+#include "components/scheduler/base/nestable_single_thread_task_runner.h"
namespace scheduler {
@@ -14,8 +14,6 @@ class NestableTaskRunnerForTest : public NestableSingleThreadTaskRunner {
static scoped_refptr<NestableTaskRunnerForTest> Create(
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
- void SetNested(bool is_nested);
-
// NestableSingleThreadTaskRunner implementation
bool PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task,
@@ -25,30 +23,18 @@ class NestableTaskRunnerForTest : public NestableSingleThreadTaskRunner {
base::TimeDelta delay) override;
bool RunsTasksOnCurrentThread() const override;
bool IsNested() const override;
- void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
- void RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) override;
protected:
~NestableTaskRunnerForTest() override;
-
- private:
NestableTaskRunnerForTest(
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
- void WrapTask(const base::PendingTask* wrapped_task);
-
+ private:
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- bool is_nested_;
-
- base::ObserverList<base::MessageLoop::TaskObserver> task_observers_;
-
- base::WeakPtr<NestableTaskRunnerForTest> weak_nestable_task_runner_ptr_;
- base::WeakPtrFactory<NestableTaskRunnerForTest> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(NestableTaskRunnerForTest);
};
} // namespace scheduler
-#endif // CONTENT_RENDERER_SCHEDULER_NESTABLE_TASK_RUNNER_FOR_TEST_H_
+#endif // CONTENT_RENDERER_SCHEDULER_BASE_NESTABLE_TASK_RUNNER_FOR_TEST_H_
diff --git a/chromium/components/scheduler/child/pollable_thread_safe_flag.cc b/chromium/components/scheduler/base/pollable_thread_safe_flag.cc
index 6a7e597ff43..13d5b6f5ec8 100644
--- a/chromium/components/scheduler/child/pollable_thread_safe_flag.cc
+++ b/chromium/components/scheduler/base/pollable_thread_safe_flag.cc
@@ -2,14 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/scheduler/child/pollable_thread_safe_flag.h"
+#include "components/scheduler/base/pollable_thread_safe_flag.h"
PollableThreadSafeFlag::PollableThreadSafeFlag(base::Lock* write_lock_)
- : flag_(false), write_lock_(write_lock_) {
-}
+ : flag_(false), write_lock_(write_lock_) {}
-PollableThreadSafeFlag::~PollableThreadSafeFlag() {
-}
+PollableThreadSafeFlag::~PollableThreadSafeFlag() {}
void PollableThreadSafeFlag::SetWhileLocked(bool value) {
write_lock_->AssertAcquired();
diff --git a/chromium/components/scheduler/child/pollable_thread_safe_flag.h b/chromium/components/scheduler/base/pollable_thread_safe_flag.h
index cf056412060..0f9aa8e632d 100644
--- a/chromium/components/scheduler/child/pollable_thread_safe_flag.h
+++ b/chromium/components/scheduler/base/pollable_thread_safe_flag.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_SCHEDULER_CHILD_POLLABLE_THREAD_SAFE_FLAG_H_
-#define COMPONENTS_SCHEDULER_CHILD_POLLABLE_THREAD_SAFE_FLAG_H_
+#ifndef COMPONENTS_SCHEDULER_BASE_POLLABLE_THREAD_SAFE_FLAG_H_
+#define COMPONENTS_SCHEDULER_BASE_POLLABLE_THREAD_SAFE_FLAG_H_
#include "base/atomicops.h"
#include "base/synchronization/lock.h"
@@ -32,4 +32,4 @@ class PollableThreadSafeFlag {
DISALLOW_COPY_AND_ASSIGN(PollableThreadSafeFlag);
};
-#endif // COMPONENTS_SCHEDULER_CHILD_POLLABLE_THREAD_SAFE_FLAG_H_
+#endif // COMPONENTS_SCHEDULER_BASE_POLLABLE_THREAD_SAFE_FLAG_H_
diff --git a/chromium/components/scheduler/base/task_queue.cc b/chromium/components/scheduler/base/task_queue.cc
new file mode 100644
index 00000000000..857860557c8
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue.cc
@@ -0,0 +1,13 @@
+// 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/scheduler/base/task_queue.h"
+
+namespace scheduler {
+
+bool TaskQueue::IsQueueEmpty() const {
+ return GetQueueState() == QueueState::EMPTY;
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue.h b/chromium/components/scheduler/base/task_queue.h
new file mode 100644
index 00000000000..abc3665e581
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue.h
@@ -0,0 +1,184 @@
+// 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_SCHEDULER_BASE_TASK_QUEUE_H_
+#define COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_H_
+
+#include "base/message_loop/message_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "components/scheduler/scheduler_export.h"
+
+namespace scheduler {
+
+class SCHEDULER_EXPORT TaskQueue : public base::SingleThreadTaskRunner {
+ public:
+ TaskQueue() {}
+
+ // Unregisters the task queue after which no tasks posted to it will run and
+ // the TaskQueueManager's reference to it will be released soon.
+ virtual void UnregisterTaskQueue() = 0;
+
+ // Post a delayed task at an absolute desired run time instead of a time
+ // delta from the current time.
+ virtual bool PostDelayedTaskAt(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeTicks desired_run_time) = 0;
+
+ enum QueuePriority {
+ // Queues with control priority will run before any other queue, and will
+ // explicitly starve other queues. Typically this should only be used for
+ // private queues which perform control operations.
+ CONTROL_PRIORITY,
+ // Queues with high priority will be selected preferentially over normal or
+ // best effort queues. The selector will ensure that high priority queues
+ // cannot completely starve normal priority queues.
+ HIGH_PRIORITY,
+ // Queues with normal priority are the default.
+ NORMAL_PRIORITY,
+ // Queues with best effort priority will only be run if all other queues are
+ // empty. They can be starved by the other queues.
+ BEST_EFFORT_PRIORITY,
+ // Queues with this priority are never run. Must be penultimate entry.
+ DISABLED_PRIORITY,
+ // Must be the last entry.
+ QUEUE_PRIORITY_COUNT,
+ FIRST_QUEUE_PRIORITY = CONTROL_PRIORITY,
+ };
+
+ // Keep TaskQueue::PumpPolicyToString in sync with this enum.
+ enum class PumpPolicy {
+ // Tasks posted to an incoming queue with an AUTO pump policy will be
+ // automatically scheduled for execution or transferred to the work queue
+ // automatically.
+ AUTO,
+ // Tasks posted to an incoming queue with an AFTER_WAKEUP pump policy
+ // will be scheduled for execution or transferred to the work queue
+ // automatically but only after another queue has executed a task.
+ AFTER_WAKEUP,
+ // Tasks posted to an incoming queue with a MANUAL will not be
+ // automatically scheduled for execution or transferred to the work queue.
+ // Instead, the selector should call PumpQueue() when necessary to bring
+ // in new tasks for execution.
+ MANUAL,
+ // Must be last entry.
+ PUMP_POLICY_COUNT,
+ FIRST_PUMP_POLICY = AUTO,
+ };
+
+ // Keep TaskQueue::WakeupPolicyToString in sync with this enum.
+ enum class WakeupPolicy {
+ // Tasks run on a queue with CAN_WAKE_OTHER_QUEUES wakeup policy can
+ // cause queues with the AFTER_WAKEUP PumpPolicy to be woken up.
+ CAN_WAKE_OTHER_QUEUES,
+ // Tasks run on a queue with DONT_WAKE_OTHER_QUEUES won't cause queues
+ // with the AFTER_WAKEUP PumpPolicy to be woken up.
+ DONT_WAKE_OTHER_QUEUES,
+ // Must be last entry.
+ WAKEUP_POLICY_COUNT,
+ FIRST_WAKEUP_POLICY = CAN_WAKE_OTHER_QUEUES,
+ };
+
+ enum class QueueState {
+ // A queue in the EMPTY state is empty and has no tasks in either the
+ // work or incoming task queue.
+ EMPTY,
+ // A queue in the NEEDS_PUMPING state has no tasks in the work task queue,
+ // but has tasks in the incoming task queue which can be pumped to make them
+ // runnable.
+ NEEDS_PUMPING,
+ // A queue in the HAS_WORK state has tasks in the work task queue which
+ // are runnable.
+ HAS_WORK,
+ };
+
+ // Options for constructing a TaskQueue. Once set the |name|,
+ // |should_monitor_quiescence| and |wakeup_policy| are immutable. The
+ // |pump_policy| can be mutated with |SetPumpPolicy()|.
+ struct Spec {
+ // Note |name| must have application lifetime.
+ explicit Spec(const char* name)
+ : name(name),
+ should_monitor_quiescence(false),
+ pump_policy(TaskQueue::PumpPolicy::AUTO),
+ wakeup_policy(TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES),
+ should_notify_observers(true) {}
+
+ Spec SetShouldMonitorQuiescence(bool should_monitor) {
+ should_monitor_quiescence = should_monitor;
+ return *this;
+ }
+
+ Spec SetPumpPolicy(PumpPolicy policy) {
+ pump_policy = policy;
+ return *this;
+ }
+
+ Spec SetWakeupPolicy(WakeupPolicy policy) {
+ wakeup_policy = policy;
+ return *this;
+ }
+
+ Spec SetShouldNotifyObservers(bool run_observers) {
+ should_notify_observers = run_observers;
+ return *this;
+ }
+
+ const char* name;
+ bool should_monitor_quiescence;
+ TaskQueue::PumpPolicy pump_policy;
+ TaskQueue::WakeupPolicy wakeup_policy;
+ bool should_notify_observers;
+ };
+
+ // Returns true if the queue priority is not
+ // TaskQueueSelector::DISABLED_PRIORITY. NOTE this must be called on the
+ // thread this TaskQueue was created by.
+ virtual bool IsQueueEnabled() const = 0;
+
+ // Returns true if there no tasks in either the work or incoming task queue.
+ // Note that this function involves taking a lock, so calling it has some
+ // overhead. NOTE this must be called on the thread this TaskQueue was created
+ // by.
+ virtual bool IsQueueEmpty() const;
+
+ // Returns the QueueState. Note that this function involves taking a lock, so
+ // calling it has some overhead.
+ virtual QueueState GetQueueState() const = 0;
+
+ // Can be called on any thread.
+ virtual const char* GetName() const = 0;
+
+ // Set the priority of the queue to |priority|. NOTE this must be called on
+ // the thread this TaskQueue was created by.
+ virtual void SetQueuePriority(QueuePriority priority) = 0;
+
+ // Set the pumping policy of the queue to |pump_policy|. NOTE this must be
+ // called on the thread this TaskQueue was created by.
+ virtual void SetPumpPolicy(PumpPolicy pump_policy) = 0;
+
+ // Reloads new tasks from the incoming queue into the work queue, regardless
+ // of whether the work queue is empty or not. After this, the function ensures
+ // that the tasks in the work queue, if any, are scheduled for execution.
+ //
+ // This function only needs to be called if automatic pumping is disabled.
+ // By default automatic pumping is enabled for all queues. NOTE this must be
+ // called on the thread this TaskQueue was created by.
+ virtual void PumpQueue() = 0;
+
+ // These functions can only be called on the same thread that the task queue
+ // manager executes its tasks on.
+ virtual void AddTaskObserver(
+ base::MessageLoop::TaskObserver* task_observer) = 0;
+ virtual void RemoveTaskObserver(
+ base::MessageLoop::TaskObserver* task_observer) = 0;
+
+ protected:
+ ~TaskQueue() override {}
+
+ DISALLOW_COPY_AND_ASSIGN(TaskQueue);
+};
+
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_H_
diff --git a/chromium/components/scheduler/base/task_queue_impl.cc b/chromium/components/scheduler/base/task_queue_impl.cc
new file mode 100644
index 00000000000..27d48db2e8e
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_impl.cc
@@ -0,0 +1,504 @@
+// 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/scheduler/base/task_queue_impl.h"
+
+#include "components/scheduler/base/task_queue_manager.h"
+
+namespace scheduler {
+namespace internal {
+
+TaskQueueImpl::TaskQueueImpl(
+ TaskQueueManager* task_queue_manager,
+ const Spec& spec,
+ const char* disabled_by_default_tracing_category,
+ const char* disabled_by_default_verbose_tracing_category)
+ : thread_id_(base::PlatformThread::CurrentId()),
+ task_queue_manager_(task_queue_manager),
+ pump_policy_(spec.pump_policy),
+ name_(spec.name),
+ disabled_by_default_tracing_category_(
+ disabled_by_default_tracing_category),
+ disabled_by_default_verbose_tracing_category_(
+ disabled_by_default_verbose_tracing_category),
+ wakeup_policy_(spec.wakeup_policy),
+ set_index_(0),
+ should_monitor_quiescence_(spec.should_monitor_quiescence),
+ should_notify_observers_(spec.should_notify_observers) {}
+
+TaskQueueImpl::~TaskQueueImpl() {}
+
+TaskQueueImpl::Task::Task()
+ : PendingTask(tracked_objects::Location(),
+ base::Closure(),
+ base::TimeTicks(),
+ true),
+#ifndef NDEBUG
+ enqueue_order_set_(false),
+#endif
+ enqueue_order_(0) {
+ sequence_num = 0;
+}
+
+TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from,
+ const base::Closure& task,
+ int sequence_number,
+ bool nestable)
+ : PendingTask(posted_from, task, base::TimeTicks(), nestable),
+#ifndef NDEBUG
+ enqueue_order_set_(false),
+#endif
+ enqueue_order_(0) {
+ sequence_num = sequence_number;
+}
+
+void TaskQueueImpl::UnregisterTaskQueue() {
+ if (!task_queue_manager_)
+ return;
+ task_queue_manager_->UnregisterTaskQueue(this);
+
+ {
+ base::AutoLock lock(lock_);
+ task_queue_manager_ = nullptr;
+ delayed_task_queue_ = std::priority_queue<Task>();
+ incoming_queue_ = std::queue<Task>();
+ work_queue_ = std::queue<Task>();
+ }
+}
+
+bool TaskQueueImpl::RunsTasksOnCurrentThread() const {
+ base::AutoLock lock(lock_);
+ return base::PlatformThread::CurrentId() == thread_id_;
+}
+
+bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) {
+ return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL);
+}
+
+bool TaskQueueImpl::PostNonNestableDelayedTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) {
+ return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE);
+}
+
+bool TaskQueueImpl::PostDelayedTaskAt(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeTicks desired_run_time) {
+ base::AutoLock lock(lock_);
+ if (!task_queue_manager_)
+ return false;
+ LazyNow lazy_now(task_queue_manager_);
+ return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time,
+ TaskType::NORMAL);
+}
+
+bool TaskQueueImpl::PostDelayedTaskImpl(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay,
+ TaskType task_type) {
+ base::AutoLock lock(lock_);
+ if (!task_queue_manager_)
+ return false;
+ LazyNow lazy_now(task_queue_manager_);
+ base::TimeTicks desired_run_time;
+ if (delay > base::TimeDelta())
+ desired_run_time = lazy_now.Now() + delay;
+ return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time,
+ task_type);
+}
+
+bool TaskQueueImpl::PostDelayedTaskLocked(
+ LazyNow* lazy_now,
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeTicks desired_run_time,
+ TaskType task_type) {
+ lock_.AssertAcquired();
+ DCHECK(task_queue_manager_);
+ Task pending_task(from_here, task,
+ task_queue_manager_->GetNextSequenceNumber(),
+ task_type != TaskType::NON_NESTABLE);
+ task_queue_manager_->DidQueueTask(pending_task);
+
+ if (!desired_run_time.is_null()) {
+ pending_task.delayed_run_time = std::max(lazy_now->Now(), desired_run_time);
+ // TODO(alexclarke): consider emplace() when C++11 library features allowed.
+ delayed_task_queue_.push(pending_task);
+ TraceQueueSize(true);
+ // Schedule a later call to MoveReadyDelayedTasksToIncomingQueue.
+ task_queue_manager_->ScheduleDelayedWork(this, desired_run_time, lazy_now);
+ return true;
+ }
+ pending_task.set_enqueue_order(pending_task.sequence_num);
+ EnqueueTaskLocked(pending_task);
+ return true;
+}
+
+void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) {
+ base::AutoLock lock(lock_);
+ if (!task_queue_manager_)
+ return;
+
+ MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now);
+}
+
+void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueueLocked(
+ LazyNow* lazy_now) {
+ lock_.AssertAcquired();
+ // Enqueue all delayed tasks that should be running now.
+ while (!delayed_task_queue_.empty() &&
+ delayed_task_queue_.top().delayed_run_time <= lazy_now->Now()) {
+ // TODO(alexclarke): consider std::move() when allowed.
+ EnqueueDelayedTaskLocked(delayed_task_queue_.top());
+ delayed_task_queue_.pop();
+ }
+ TraceQueueSize(true);
+}
+
+bool TaskQueueImpl::IsQueueEnabled() const {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ if (!task_queue_manager_)
+ return false;
+
+ return task_queue_manager_->selector_.IsQueueEnabled(this);
+}
+
+TaskQueue::QueueState TaskQueueImpl::GetQueueState() const {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ if (!work_queue_.empty())
+ return QueueState::HAS_WORK;
+
+ {
+ base::AutoLock lock(lock_);
+ if (incoming_queue_.empty()) {
+ return QueueState::EMPTY;
+ } else {
+ return QueueState::NEEDS_PUMPING;
+ }
+ }
+}
+
+bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const Task* task) {
+ lock_.AssertAcquired();
+ // A null task is passed when UpdateQueue is called before any task is run.
+ // In this case we don't want to pump an after_wakeup queue, so return true
+ // here.
+ if (!task)
+ return true;
+
+ // Return false if there are no task in the incoming queue.
+ if (incoming_queue_.empty())
+ return false;
+
+ const TaskQueueImpl::Task& oldest_queued_task = incoming_queue_.front();
+ return task->enqueue_order() < oldest_queued_task.enqueue_order();
+}
+
+bool TaskQueueImpl::ShouldAutoPumpQueueLocked(bool should_trigger_wakeup,
+ const Task* previous_task) {
+ lock_.AssertAcquired();
+ if (pump_policy_ == PumpPolicy::MANUAL)
+ return false;
+ if (pump_policy_ == PumpPolicy::AFTER_WAKEUP &&
+ (!should_trigger_wakeup || TaskIsOlderThanQueuedTasks(previous_task)))
+ return false;
+ if (incoming_queue_.empty())
+ return false;
+ return true;
+}
+
+bool TaskQueueImpl::NextPendingDelayedTaskRunTime(
+ base::TimeTicks* next_pending_delayed_task) {
+ base::AutoLock lock(lock_);
+ if (delayed_task_queue_.empty())
+ return false;
+ *next_pending_delayed_task = delayed_task_queue_.top().delayed_run_time;
+ return true;
+}
+
+void TaskQueueImpl::UpdateWorkQueue(LazyNow* lazy_now,
+ bool should_trigger_wakeup,
+ const Task* previous_task) {
+ DCHECK(work_queue_.empty());
+ base::AutoLock lock(lock_);
+ if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task))
+ return;
+ MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now);
+ std::swap(work_queue_, incoming_queue_);
+ // |incoming_queue_| is now empty so TaskQueueManager::UpdateQueues no
+ // longer needs to consider this queue for reloading.
+ task_queue_manager_->UnregisterAsUpdatableTaskQueue(this);
+ if (!work_queue_.empty()) {
+ DCHECK(task_queue_manager_);
+ task_queue_manager_->selector_.GetTaskQueueSets()->OnPushQueue(this);
+ TraceQueueSize(true);
+ }
+}
+
+TaskQueueImpl::Task TaskQueueImpl::TakeTaskFromWorkQueue() {
+ // TODO(alexclarke): consider std::move() when allowed.
+ Task pending_task = work_queue_.front();
+ work_queue_.pop();
+ DCHECK(task_queue_manager_);
+ task_queue_manager_->selector_.GetTaskQueueSets()->OnPopQueue(this);
+ TraceQueueSize(false);
+ return pending_task;
+}
+
+void TaskQueueImpl::TraceQueueSize(bool is_locked) const {
+ bool is_tracing;
+ TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_,
+ &is_tracing);
+ if (!is_tracing)
+ return;
+ if (!is_locked)
+ lock_.Acquire();
+ else
+ lock_.AssertAcquired();
+ TRACE_COUNTER1(
+ disabled_by_default_tracing_category_, GetName(),
+ incoming_queue_.size() + work_queue_.size() + delayed_task_queue_.size());
+ if (!is_locked)
+ lock_.Release();
+}
+
+void TaskQueueImpl::EnqueueTaskLocked(const Task& pending_task) {
+ lock_.AssertAcquired();
+ if (!task_queue_manager_)
+ return;
+ if (incoming_queue_.empty())
+ task_queue_manager_->RegisterAsUpdatableTaskQueue(this);
+ if (pump_policy_ == PumpPolicy::AUTO && incoming_queue_.empty()) {
+ task_queue_manager_->MaybePostDoWorkOnMainRunner();
+ }
+ // TODO(alexclarke): consider std::move() when allowed.
+ incoming_queue_.push(pending_task);
+ TraceQueueSize(true);
+}
+
+void TaskQueueImpl::EnqueueDelayedTaskLocked(const Task& pending_task) {
+ lock_.AssertAcquired();
+ if (!task_queue_manager_)
+ return;
+ if (incoming_queue_.empty())
+ task_queue_manager_->RegisterAsUpdatableTaskQueue(this);
+ // TODO(alexclarke): consider std::move() when allowed.
+ incoming_queue_.push(pending_task);
+ incoming_queue_.back().set_enqueue_order(
+ task_queue_manager_->GetNextSequenceNumber());
+ TraceQueueSize(true);
+}
+
+void TaskQueueImpl::SetPumpPolicy(PumpPolicy pump_policy) {
+ base::AutoLock lock(lock_);
+ if (pump_policy == PumpPolicy::AUTO && pump_policy_ != PumpPolicy::AUTO) {
+ PumpQueueLocked();
+ }
+ pump_policy_ = pump_policy;
+}
+
+void TaskQueueImpl::PumpQueueLocked() {
+ lock_.AssertAcquired();
+ if (!task_queue_manager_)
+ return;
+
+ LazyNow lazy_now(task_queue_manager_);
+ MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now);
+
+ bool was_empty = work_queue_.empty();
+ while (!incoming_queue_.empty()) {
+ // TODO(alexclarke): consider std::move() when allowed.
+ work_queue_.push(incoming_queue_.front());
+ incoming_queue_.pop();
+ }
+ // |incoming_queue_| is now empty so TaskQueueManager::UpdateQueues no longer
+ // needs to consider this queue for reloading.
+ task_queue_manager_->UnregisterAsUpdatableTaskQueue(this);
+ if (!work_queue_.empty()) {
+ if (was_empty)
+ task_queue_manager_->selector_.GetTaskQueueSets()->OnPushQueue(this);
+ task_queue_manager_->MaybePostDoWorkOnMainRunner();
+ }
+}
+
+void TaskQueueImpl::PumpQueue() {
+ base::AutoLock lock(lock_);
+ PumpQueueLocked();
+}
+
+const char* TaskQueueImpl::GetName() const {
+ return name_;
+}
+
+bool TaskQueueImpl::GetWorkQueueFrontTaskEnqueueOrder(
+ int* enqueue_order) const {
+ if (work_queue_.empty())
+ return false;
+ *enqueue_order = work_queue_.front().enqueue_order();
+ return true;
+}
+
+void TaskQueueImpl::PushTaskOntoWorkQueueForTest(const Task& task) {
+ work_queue_.push(task);
+}
+
+void TaskQueueImpl::PopTaskFromWorkQueueForTest() {
+ work_queue_.pop();
+}
+
+void TaskQueueImpl::SetQueuePriority(QueuePriority priority) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ if (!task_queue_manager_)
+ return;
+
+ task_queue_manager_->selector_.SetQueuePriority(this, priority);
+}
+
+// static
+const char* TaskQueueImpl::PumpPolicyToString(
+ TaskQueue::PumpPolicy pump_policy) {
+ switch (pump_policy) {
+ case TaskQueue::PumpPolicy::AUTO:
+ return "auto";
+ case TaskQueue::PumpPolicy::AFTER_WAKEUP:
+ return "after_wakeup";
+ case TaskQueue::PumpPolicy::MANUAL:
+ return "manual";
+ default:
+ NOTREACHED();
+ return nullptr;
+ }
+}
+
+// static
+const char* TaskQueueImpl::WakeupPolicyToString(
+ TaskQueue::WakeupPolicy wakeup_policy) {
+ switch (wakeup_policy) {
+ case TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES:
+ return "can_wake_other_queues";
+ case TaskQueue::WakeupPolicy::DONT_WAKE_OTHER_QUEUES:
+ return "dont_wake_other_queues";
+ default:
+ NOTREACHED();
+ return nullptr;
+ }
+}
+
+// static
+const char* TaskQueueImpl::PriorityToString(QueuePriority priority) {
+ switch (priority) {
+ case CONTROL_PRIORITY:
+ return "control";
+ case HIGH_PRIORITY:
+ return "high";
+ case NORMAL_PRIORITY:
+ return "normal";
+ case BEST_EFFORT_PRIORITY:
+ return "best_effort";
+ case DISABLED_PRIORITY:
+ return "disabled";
+ default:
+ NOTREACHED();
+ return nullptr;
+ }
+}
+
+void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
+ base::AutoLock lock(lock_);
+ state->BeginDictionary();
+ state->SetString("name", GetName());
+ state->SetString("pump_policy", PumpPolicyToString(pump_policy_));
+ state->SetString("wakeup_policy", WakeupPolicyToString(wakeup_policy_));
+ bool verbose_tracing_enabled = false;
+ TRACE_EVENT_CATEGORY_GROUP_ENABLED(
+ disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled);
+ state->SetInteger("incoming_queue_size", incoming_queue_.size());
+ state->SetInteger("work_queue_size", work_queue_.size());
+ state->SetInteger("delayed_task_queue_size", delayed_task_queue_.size());
+ if (verbose_tracing_enabled) {
+ state->BeginArray("incoming_queue");
+ QueueAsValueInto(incoming_queue_, state);
+ state->EndArray();
+ state->BeginArray("work_queue");
+ QueueAsValueInto(work_queue_, state);
+ state->EndArray();
+ state->BeginArray("delayed_task_queue");
+ QueueAsValueInto(delayed_task_queue_, state);
+ state->EndArray();
+ }
+ state->SetString("priority",
+ PriorityToString(static_cast<QueuePriority>(set_index_)));
+ state->EndDictionary();
+}
+
+void TaskQueueImpl::AddTaskObserver(
+ base::MessageLoop::TaskObserver* task_observer) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ task_observers_.AddObserver(task_observer);
+}
+
+void TaskQueueImpl::RemoveTaskObserver(
+ base::MessageLoop::TaskObserver* task_observer) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ task_observers_.RemoveObserver(task_observer);
+}
+
+void TaskQueueImpl::NotifyWillProcessTask(
+ const base::PendingTask& pending_task) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ DCHECK(should_notify_observers_);
+ FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_,
+ WillProcessTask(pending_task));
+}
+
+void TaskQueueImpl::NotifyDidProcessTask(
+ const base::PendingTask& pending_task) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ DCHECK(should_notify_observers_);
+ FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_,
+ DidProcessTask(pending_task));
+}
+
+// static
+void TaskQueueImpl::QueueAsValueInto(const std::queue<Task>& queue,
+ base::trace_event::TracedValue* state) {
+ std::queue<Task> queue_copy(queue);
+ while (!queue_copy.empty()) {
+ TaskAsValueInto(queue_copy.front(), state);
+ queue_copy.pop();
+ }
+}
+
+// static
+void TaskQueueImpl::QueueAsValueInto(const std::priority_queue<Task>& queue,
+ base::trace_event::TracedValue* state) {
+ std::priority_queue<Task> queue_copy(queue);
+ while (!queue_copy.empty()) {
+ TaskAsValueInto(queue_copy.top(), state);
+ queue_copy.pop();
+ }
+}
+
+// static
+void TaskQueueImpl::TaskAsValueInto(const Task& task,
+ base::trace_event::TracedValue* state) {
+ state->BeginDictionary();
+ state->SetString("posted_from", task.posted_from.ToString());
+ state->SetInteger("enqueue_order", task.enqueue_order());
+ state->SetInteger("sequence_num", task.sequence_num);
+ state->SetBoolean("nestable", task.nestable);
+ state->SetBoolean("is_high_res", task.is_high_res);
+ state->SetDouble(
+ "delayed_run_time",
+ (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L);
+ state->EndDictionary();
+}
+
+} // namespace internal
+} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_impl.h b/chromium/components/scheduler/base/task_queue_impl.h
new file mode 100644
index 00000000000..8e2fa634061
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_impl.h
@@ -0,0 +1,212 @@
+// 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 CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
+#define CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
+
+#include <set>
+
+#include "base/pending_task.h"
+#include "base/threading/thread_checker.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "components/scheduler/base/lazy_now.h"
+#include "components/scheduler/base/task_queue.h"
+#include "components/scheduler/scheduler_export.h"
+
+namespace scheduler {
+class TaskQueueManager;
+
+namespace internal {
+
+class SCHEDULER_EXPORT TaskQueueImpl final : public TaskQueue {
+ public:
+ TaskQueueImpl(TaskQueueManager* task_queue_manager,
+ const Spec& spec,
+ const char* disabled_by_default_tracing_category,
+ const char* disabled_by_default_verbose_tracing_category);
+
+ class SCHEDULER_EXPORT Task : public base::PendingTask {
+ public:
+ Task();
+ Task(const tracked_objects::Location& posted_from,
+ const base::Closure& task,
+ int sequence_number,
+ bool nestable);
+
+ int enqueue_order() const {
+#ifndef NDEBUG
+ DCHECK(enqueue_order_set_);
+#endif
+ return enqueue_order_;
+ }
+
+ void set_enqueue_order(int enqueue_order) {
+#ifndef NDEBUG
+ DCHECK(!enqueue_order_set_);
+ enqueue_order_set_ = true;
+#endif
+ enqueue_order_ = enqueue_order;
+ }
+
+ private:
+#ifndef NDEBUG
+ bool enqueue_order_set_;
+#endif
+ // Similar to sequence number, but the |enqueue_order| is set by
+ // EnqueueTasksLocked and is not initially defined for delayed tasks until
+ // they are enqueued on the |incoming_queue_|.
+ int enqueue_order_;
+ };
+
+ // TaskQueue implementation.
+ void UnregisterTaskQueue() override;
+ bool RunsTasksOnCurrentThread() const override;
+ bool PostDelayedTask(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) override;
+ bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) override;
+ bool PostDelayedTaskAt(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeTicks desired_run_time) override;
+
+ bool IsQueueEnabled() const override;
+ QueueState GetQueueState() const override;
+ void SetQueuePriority(QueuePriority priority) override;
+ void PumpQueue() override;
+ void SetPumpPolicy(PumpPolicy pump_policy) override;
+ void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
+ void RemoveTaskObserver(
+ base::MessageLoop::TaskObserver* task_observer) override;
+
+ bool NextPendingDelayedTaskRunTime(
+ base::TimeTicks* next_pending_delayed_task);
+
+ void UpdateWorkQueue(LazyNow* lazy_now,
+ bool should_trigger_wakeup,
+ const Task* previous_task);
+ Task TakeTaskFromWorkQueue();
+
+ std::queue<Task>& work_queue() { return work_queue_; }
+
+ WakeupPolicy wakeup_policy() const {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ return wakeup_policy_;
+ }
+
+ const char* GetName() const override;
+
+ void AsValueInto(base::trace_event::TracedValue* state) const;
+
+ size_t get_task_queue_set_index() const { return set_index_; }
+
+ void set_task_queue_set_index(size_t set_index) { set_index_ = set_index; }
+
+ // If the work queue isn't empty, |enqueue_order| gets set to the enqueue
+ // order of the front task and the function returns true. Otherwise the
+ // function returns false.
+ bool GetWorkQueueFrontTaskEnqueueOrder(int* enqueue_order) const;
+
+ bool GetQuiescenceMonitored() const { return should_monitor_quiescence_; }
+ bool GetShouldNotifyObservers() const { return should_notify_observers_; }
+
+ void NotifyWillProcessTask(const base::PendingTask& pending_task);
+ void NotifyDidProcessTask(const base::PendingTask& pending_task);
+
+ // Delayed task posted to the underlying run loop, which locks |lock_| and
+ // calls MoveReadyDelayedTasksToIncomingQueueLocked to process dealyed tasks
+ // that need to be run now. Thread safe, but in practice it's always called
+ // from the main thread.
+ void MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now);
+
+ // Test support functions. These should not be used in production code.
+ void PushTaskOntoWorkQueueForTest(const Task& task);
+ void PopTaskFromWorkQueueForTest();
+ size_t WorkQueueSizeForTest() const { return work_queue_.size(); }
+
+ // Can be called on any thread.
+ static const char* PumpPolicyToString(TaskQueue::PumpPolicy pump_policy);
+
+ // Can be called on any thread.
+ static const char* WakeupPolicyToString(
+ TaskQueue::WakeupPolicy wakeup_policy);
+
+ // Can be called on any thread.
+ static const char* PriorityToString(TaskQueue::QueuePriority priority);
+
+ private:
+ enum class TaskType {
+ NORMAL,
+ NON_NESTABLE,
+ };
+
+ ~TaskQueueImpl() override;
+
+ bool PostDelayedTaskImpl(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay,
+ TaskType task_type);
+ bool PostDelayedTaskLocked(LazyNow* lazy_now,
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeTicks desired_run_time,
+ TaskType task_type);
+
+ // Enqueues any delayed tasks which should be run now on the incoming_queue_
+ // and calls ScheduleDelayedWorkLocked to ensure future tasks are scheduled.
+ // Must be called with |lock_| locked.
+ void MoveReadyDelayedTasksToIncomingQueueLocked(LazyNow* lazy_now);
+
+ void PumpQueueLocked();
+ bool TaskIsOlderThanQueuedTasks(const Task* task);
+ bool ShouldAutoPumpQueueLocked(bool should_trigger_wakeup,
+ const Task* previous_task);
+
+ // Push the task onto the |incoming_queue_| and for auto pumped queues it
+ // calls MaybePostDoWorkOnMainRunner if the incomming queue was empty.
+ void EnqueueTaskLocked(const Task& pending_task);
+
+ // Push the task onto the |incoming_queue_| and allocates an
+ // enqueue_order for it based on |enqueue_order_policy|. Does not call
+ // MaybePostDoWorkOnMainRunner!
+ void EnqueueDelayedTaskLocked(const Task& pending_task);
+
+ void TraceQueueSize(bool is_locked) const;
+ static void QueueAsValueInto(const std::queue<Task>& queue,
+ base::trace_event::TracedValue* state);
+ static void QueueAsValueInto(const std::priority_queue<Task>& queue,
+ base::trace_event::TracedValue* state);
+ static void TaskAsValueInto(const Task& task,
+ base::trace_event::TracedValue* state);
+
+ // This lock protects all members in the contigious block below.
+ // TODO(alexclarke): Group all the members protected by the lock into a struct
+ mutable base::Lock lock_;
+ base::PlatformThreadId thread_id_;
+ TaskQueueManager* task_queue_manager_;
+ std::queue<Task> incoming_queue_;
+ PumpPolicy pump_policy_;
+ std::priority_queue<Task> delayed_task_queue_;
+
+ const char* name_;
+ const char* disabled_by_default_tracing_category_;
+ const char* disabled_by_default_verbose_tracing_category_;
+
+ base::ThreadChecker main_thread_checker_;
+ std::queue<Task> work_queue_;
+ base::ObserverList<base::MessageLoop::TaskObserver> task_observers_;
+ WakeupPolicy wakeup_policy_;
+ size_t set_index_;
+ bool should_monitor_quiescence_;
+ bool should_notify_observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskQueueImpl);
+};
+
+} // namespace internal
+} // namespace scheduler
+
+#endif // CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
diff --git a/chromium/components/scheduler/base/task_queue_manager.cc b/chromium/components/scheduler/base/task_queue_manager.cc
new file mode 100644
index 00000000000..00f07349d98
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_manager.cc
@@ -0,0 +1,464 @@
+// 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/scheduler/base/task_queue_manager.h"
+
+#include <queue>
+#include <set>
+
+#include "base/bind.h"
+#include "base/time/default_tick_clock.h"
+#include "components/scheduler/base/lazy_now.h"
+#include "components/scheduler/base/nestable_single_thread_task_runner.h"
+#include "components/scheduler/base/task_queue_impl.h"
+#include "components/scheduler/base/task_queue_selector.h"
+#include "components/scheduler/base/task_queue_sets.h"
+
+namespace {
+const int64_t kMaxTimeTicks = std::numeric_limits<int64>::max();
+}
+
+namespace scheduler {
+
+TaskQueueManager::TaskQueueManager(
+ scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
+ const char* disabled_by_default_tracing_category,
+ const char* disabled_by_default_verbose_tracing_category)
+ : main_task_runner_(main_task_runner),
+ task_was_run_on_quiescence_monitored_queue_(false),
+ pending_dowork_count_(0),
+ work_batch_size_(1),
+ time_source_(new base::DefaultTickClock),
+ disabled_by_default_tracing_category_(
+ disabled_by_default_tracing_category),
+ disabled_by_default_verbose_tracing_category_(
+ disabled_by_default_verbose_tracing_category),
+ observer_(nullptr),
+ deletion_sentinel_(new DeletionSentinel()),
+ weak_factory_(this) {
+ DCHECK(main_task_runner->RunsTasksOnCurrentThread());
+ TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category,
+ "TaskQueueManager", this);
+ selector_.SetTaskQueueSelectorObserver(this);
+
+ do_work_from_main_thread_closure_ =
+ base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), true);
+ do_work_from_other_thread_closure_ =
+ base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), false);
+ delayed_queue_wakeup_closure_ =
+ base::Bind(&TaskQueueManager::DelayedDoWork, weak_factory_.GetWeakPtr());
+}
+
+TaskQueueManager::~TaskQueueManager() {
+ TRACE_EVENT_OBJECT_DELETED_WITH_ID(disabled_by_default_tracing_category_,
+ "TaskQueueManager", this);
+
+ while (!queues_.empty())
+ (*queues_.begin())->UnregisterTaskQueue();
+
+ selector_.SetTaskQueueSelectorObserver(nullptr);
+}
+
+scoped_refptr<internal::TaskQueueImpl> TaskQueueManager::NewTaskQueue(
+ const TaskQueue::Spec& spec) {
+ TRACE_EVENT1(disabled_by_default_tracing_category_,
+ "TaskQueueManager::NewTaskQueue", "queue_name", spec.name);
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ scoped_refptr<internal::TaskQueueImpl> queue(
+ make_scoped_refptr(new internal::TaskQueueImpl(
+ this, spec, disabled_by_default_tracing_category_,
+ disabled_by_default_verbose_tracing_category_)));
+ queues_.insert(queue);
+ selector_.AddQueue(queue.get());
+ return queue;
+}
+
+void TaskQueueManager::SetObserver(Observer* observer) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ observer_ = observer;
+}
+
+void TaskQueueManager::UnregisterTaskQueue(
+ scoped_refptr<internal::TaskQueueImpl> task_queue) {
+ TRACE_EVENT1(disabled_by_default_tracing_category_,
+ "TaskQueueManager::UnregisterTaskQueue", "queue_name",
+ task_queue->GetName());
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ if (observer_)
+ observer_->OnUnregisterTaskQueue(task_queue);
+
+ // Add |task_queue| to |queues_to_delete_| so we can prevent it from being
+ // freed while any of our structures hold hold a raw pointer to it.
+ queues_to_delete_.insert(task_queue);
+ queues_.erase(task_queue);
+ selector_.RemoveQueue(task_queue.get());
+
+ // We need to remove |task_queue| from delayed_wakeup_map_ which is a little
+ // awkward since it's keyed by time. O(n) running time.
+ for (DelayedWakeupMultimap::iterator iter = delayed_wakeup_map_.begin();
+ iter != delayed_wakeup_map_.end();) {
+ if (iter->second == task_queue.get()) {
+ DelayedWakeupMultimap::iterator temp = iter;
+ iter++;
+ // O(1) amortized.
+ delayed_wakeup_map_.erase(temp);
+ } else {
+ iter++;
+ }
+ }
+
+ // |newly_updatable_| might contain |task_queue|, we use
+ // MoveNewlyUpdatableQueuesIntoUpdatableQueueSet to flush it out.
+ MoveNewlyUpdatableQueuesIntoUpdatableQueueSet();
+ updatable_queue_set_.erase(task_queue.get());
+}
+
+base::TimeTicks TaskQueueManager::NextPendingDelayedTaskRunTime() {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ bool found_pending_task = false;
+ base::TimeTicks next_pending_delayed_task(
+ base::TimeTicks::FromInternalValue(kMaxTimeTicks));
+ for (auto& queue : queues_) {
+ base::TimeTicks queues_next_pending_delayed_task;
+ if (queue->NextPendingDelayedTaskRunTime(
+ &queues_next_pending_delayed_task)) {
+ found_pending_task = true;
+ next_pending_delayed_task =
+ std::min(next_pending_delayed_task, queues_next_pending_delayed_task);
+ }
+ }
+
+ if (!found_pending_task)
+ return base::TimeTicks();
+
+ DCHECK_NE(next_pending_delayed_task,
+ base::TimeTicks::FromInternalValue(kMaxTimeTicks));
+ return next_pending_delayed_task;
+}
+
+void TaskQueueManager::RegisterAsUpdatableTaskQueue(
+ internal::TaskQueueImpl* queue) {
+ base::AutoLock lock(newly_updatable_lock_);
+ newly_updatable_.push_back(queue);
+}
+
+void TaskQueueManager::UnregisterAsUpdatableTaskQueue(
+ internal::TaskQueueImpl* queue) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ updatable_queue_set_.erase(queue);
+}
+
+void TaskQueueManager::MoveNewlyUpdatableQueuesIntoUpdatableQueueSet() {
+ base::AutoLock lock(newly_updatable_lock_);
+ while (!newly_updatable_.empty()) {
+ updatable_queue_set_.insert(newly_updatable_.back());
+ newly_updatable_.pop_back();
+ }
+}
+
+void TaskQueueManager::UpdateWorkQueues(
+ bool should_trigger_wakeup,
+ const internal::TaskQueueImpl::Task* previous_task) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ TRACE_EVENT0(disabled_by_default_tracing_category_,
+ "TaskQueueManager::UpdateWorkQueues");
+ internal::LazyNow lazy_now(this);
+
+ // Move any ready delayed tasks into the incomming queues.
+ WakeupReadyDelayedQueues(&lazy_now);
+
+ // Insert any newly updatable queues into the updatable_queue_set_.
+ {
+ base::AutoLock lock(newly_updatable_lock_);
+ while (!newly_updatable_.empty()) {
+ updatable_queue_set_.insert(newly_updatable_.back());
+ newly_updatable_.pop_back();
+ }
+ }
+
+ auto iter = updatable_queue_set_.begin();
+ while (iter != updatable_queue_set_.end()) {
+ internal::TaskQueueImpl* queue = *iter++;
+ // NOTE Update work queue may erase itself from |updatable_queue_set_|.
+ // This is fine, erasing an element won't invalidate any interator, as long
+ // as the iterator isn't the element being delated.
+ if (queue->work_queue().empty())
+ queue->UpdateWorkQueue(&lazy_now, should_trigger_wakeup, previous_task);
+ }
+}
+
+void TaskQueueManager::ScheduleDelayedWorkTask(
+ scoped_refptr<internal::TaskQueueImpl> queue,
+ base::TimeTicks delayed_run_time) {
+ internal::LazyNow lazy_now(this);
+ ScheduleDelayedWork(queue.get(), delayed_run_time, &lazy_now);
+}
+
+void TaskQueueManager::ScheduleDelayedWork(internal::TaskQueueImpl* queue,
+ base::TimeTicks delayed_run_time,
+ internal::LazyNow* lazy_now) {
+ if (!main_task_runner_->BelongsToCurrentThread()) {
+ // NOTE posting a delayed task from a different thread is not expected to be
+ // common. This pathway is less optimal than perhaps it could be because
+ // it causes two main thread tasks to be run. Should this assumption prove
+ // to be false in future, we may need to revisit this.
+ main_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&TaskQueueManager::ScheduleDelayedWorkTask,
+ weak_factory_.GetWeakPtr(),
+ scoped_refptr<internal::TaskQueueImpl>(queue),
+ delayed_run_time));
+ return;
+ }
+ if (delayed_run_time > lazy_now->Now()) {
+ // Make sure there's one (and only one) task posted to |main_task_runner_|
+ // to call |DelayedDoWork| at |delayed_run_time|.
+ if (delayed_wakeup_map_.find(delayed_run_time) ==
+ delayed_wakeup_map_.end()) {
+ base::TimeDelta delay = delayed_run_time - lazy_now->Now();
+ main_task_runner_->PostDelayedTask(FROM_HERE,
+ delayed_queue_wakeup_closure_, delay);
+ }
+ delayed_wakeup_map_.insert(std::make_pair(delayed_run_time, queue));
+ } else {
+ WakeupReadyDelayedQueues(lazy_now);
+ }
+}
+
+void TaskQueueManager::DelayedDoWork() {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+
+ {
+ internal::LazyNow lazy_now(this);
+ WakeupReadyDelayedQueues(&lazy_now);
+ }
+
+ DoWork(false);
+}
+
+void TaskQueueManager::WakeupReadyDelayedQueues(internal::LazyNow* lazy_now) {
+ // Wake up any queues with pending delayed work. Note std::multipmap stores
+ // the elements sorted by key, so the begin() iterator points to the earliest
+ // queue to wakeup.
+ std::set<internal::TaskQueueImpl*> dedup_set;
+ while (!delayed_wakeup_map_.empty()) {
+ DelayedWakeupMultimap::iterator next_wakeup = delayed_wakeup_map_.begin();
+ if (next_wakeup->first > lazy_now->Now())
+ break;
+ // A queue could have any number of delayed tasks pending so it's worthwhile
+ // deduping calls to MoveReadyDelayedTasksToIncomingQueue since it takes a
+ // lock. NOTE the order in which these are called matters since the order
+ // in which EnqueueTaskLocks is called is respected when choosing which
+ // queue to execute a task from.
+ if (dedup_set.insert(next_wakeup->second).second)
+ next_wakeup->second->MoveReadyDelayedTasksToIncomingQueue(lazy_now);
+ delayed_wakeup_map_.erase(next_wakeup);
+ }
+}
+
+void TaskQueueManager::MaybePostDoWorkOnMainRunner() {
+ bool on_main_thread = main_task_runner_->BelongsToCurrentThread();
+ if (on_main_thread) {
+ // We only want one pending DoWork posted from the main thread, or we risk
+ // an explosion of pending DoWorks which could starve out everything else.
+ if (pending_dowork_count_ > 0) {
+ return;
+ }
+ pending_dowork_count_++;
+ main_task_runner_->PostTask(FROM_HERE, do_work_from_main_thread_closure_);
+ } else {
+ main_task_runner_->PostTask(FROM_HERE, do_work_from_other_thread_closure_);
+ }
+}
+
+void TaskQueueManager::DoWork(bool decrement_pending_dowork_count) {
+ if (decrement_pending_dowork_count) {
+ pending_dowork_count_--;
+ DCHECK_GE(pending_dowork_count_, 0);
+ }
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+
+ queues_to_delete_.clear();
+
+ // Pass false and nullptr to UpdateWorkQueues here to prevent waking up a
+ // pump-after-wakeup queue.
+ UpdateWorkQueues(false, nullptr);
+
+ internal::TaskQueueImpl::Task previous_task;
+ for (int i = 0; i < work_batch_size_; i++) {
+ internal::TaskQueueImpl* queue;
+ if (!SelectQueueToService(&queue))
+ break;
+
+ switch (ProcessTaskFromWorkQueue(queue, &previous_task)) {
+ case ProcessTaskResult::DEFERRED:
+ // If a task was deferred, try again with another task. Note that this
+ // means deferred tasks (i.e. non-nestable tasks) will never trigger
+ // queue wake-ups.
+ continue;
+ case ProcessTaskResult::EXECUTED:
+ break;
+ case ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED:
+ return; // The TaskQueueManager got deleted, we must bail out.
+ }
+ bool should_trigger_wakeup = queue->wakeup_policy() ==
+ TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES;
+ UpdateWorkQueues(should_trigger_wakeup, &previous_task);
+
+ // Only run a single task per batch in nested run loops so that we can
+ // properly exit the nested loop when someone calls RunLoop::Quit().
+ if (main_task_runner_->IsNested())
+ break;
+ }
+
+ // TODO(alexclarke): Consider refactoring the above loop to terminate only
+ // when there's no more work left to be done, rather than posting a
+ // continuation task.
+ if (!selector_.EnabledWorkQueuesEmpty())
+ MaybePostDoWorkOnMainRunner();
+}
+
+bool TaskQueueManager::SelectQueueToService(
+ internal::TaskQueueImpl** out_queue) {
+ bool should_run = selector_.SelectQueueToService(out_queue);
+ TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
+ disabled_by_default_tracing_category_, "TaskQueueManager", this,
+ AsValueWithSelectorResult(should_run, *out_queue));
+ return should_run;
+}
+
+void TaskQueueManager::DidQueueTask(
+ const internal::TaskQueueImpl::Task& pending_task) {
+ task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task);
+}
+
+TaskQueueManager::ProcessTaskResult TaskQueueManager::ProcessTaskFromWorkQueue(
+ internal::TaskQueueImpl* queue,
+ internal::TaskQueueImpl::Task* out_previous_task) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ scoped_refptr<DeletionSentinel> protect(deletion_sentinel_);
+ // TODO(alexclarke): consider std::move() when allowed.
+ internal::TaskQueueImpl::Task pending_task = queue->TakeTaskFromWorkQueue();
+
+ if (queue->GetQuiescenceMonitored())
+ task_was_run_on_quiescence_monitored_queue_ = true;
+
+ if (!pending_task.nestable && main_task_runner_->IsNested()) {
+ // Defer non-nestable work to the main task runner. NOTE these tasks can be
+ // arbitrarily delayed so the additional delay should not be a problem.
+ // TODO(skyostil): Figure out a way to not forget which task queue the
+ // task is associated with. See http://crbug.com/522843.
+ main_task_runner_->PostNonNestableTask(pending_task.posted_from,
+ pending_task.task);
+ return ProcessTaskResult::DEFERRED;
+ }
+
+ TRACE_TASK_EXECUTION("TaskQueueManager::ProcessTaskFromWorkQueue",
+ pending_task);
+ if (queue->GetShouldNotifyObservers()) {
+ FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_,
+ WillProcessTask(pending_task));
+ queue->NotifyWillProcessTask(pending_task);
+ }
+ TRACE_EVENT1(disabled_by_default_tracing_category_,
+ "TaskQueueManager::RunTask", "queue", queue->GetName());
+ task_annotator_.RunTask("TaskQueueManager::PostTask", pending_task);
+
+ // Detect if the TaskQueueManager just got deleted. If this happens we must
+ // not access any member variables after this point.
+ if (protect->HasOneRef())
+ return ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED;
+
+ if (queue->GetShouldNotifyObservers()) {
+ FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_,
+ DidProcessTask(pending_task));
+ queue->NotifyDidProcessTask(pending_task);
+ }
+
+ pending_task.task.Reset();
+ *out_previous_task = pending_task;
+ return ProcessTaskResult::EXECUTED;
+}
+
+bool TaskQueueManager::RunsTasksOnCurrentThread() const {
+ return main_task_runner_->RunsTasksOnCurrentThread();
+}
+
+bool TaskQueueManager::PostDelayedTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) {
+ DCHECK_GE(delay, base::TimeDelta());
+ return main_task_runner_->PostDelayedTask(from_here, task, delay);
+}
+
+void TaskQueueManager::SetWorkBatchSize(int work_batch_size) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ DCHECK_GE(work_batch_size, 1);
+ work_batch_size_ = work_batch_size;
+}
+
+void TaskQueueManager::AddTaskObserver(
+ base::MessageLoop::TaskObserver* task_observer) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ task_observers_.AddObserver(task_observer);
+}
+
+void TaskQueueManager::RemoveTaskObserver(
+ base::MessageLoop::TaskObserver* task_observer) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ task_observers_.RemoveObserver(task_observer);
+}
+
+void TaskQueueManager::SetTimeSourceForTesting(
+ scoped_ptr<base::TickClock> time_source) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ time_source_ = time_source.Pass();
+}
+
+bool TaskQueueManager::GetAndClearSystemIsQuiescentBit() {
+ bool task_was_run = task_was_run_on_quiescence_monitored_queue_;
+ task_was_run_on_quiescence_monitored_queue_ = false;
+ return !task_was_run;
+}
+
+base::TimeTicks TaskQueueManager::Now() const {
+ return time_source_->NowTicks();
+}
+
+int TaskQueueManager::GetNextSequenceNumber() {
+ return task_sequence_num_.GetNext();
+}
+
+scoped_refptr<base::trace_event::ConvertableToTraceFormat>
+TaskQueueManager::AsValueWithSelectorResult(
+ bool should_run,
+ internal::TaskQueueImpl* selected_queue) const {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ scoped_refptr<base::trace_event::TracedValue> state =
+ new base::trace_event::TracedValue();
+ state->BeginArray("queues");
+ for (auto& queue : queues_)
+ queue->AsValueInto(state.get());
+ state->EndArray();
+ state->BeginDictionary("selector");
+ selector_.AsValueInto(state.get());
+ state->EndDictionary();
+ if (should_run)
+ state->SetString("selected_queue", selected_queue->GetName());
+
+ state->BeginArray("updatable_queue_set");
+ for (auto& queue : updatable_queue_set_)
+ state->AppendString(queue->GetName());
+ state->EndArray();
+ return state;
+}
+
+void TaskQueueManager::OnTaskQueueEnabled(internal::TaskQueueImpl* queue) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ // Only schedule DoWork if there's something to do.
+ if (!queue->work_queue().empty())
+ MaybePostDoWorkOnMainRunner();
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_manager.h b/chromium/components/scheduler/base/task_queue_manager.h
new file mode 100644
index 00000000000..ee305d40c49
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_manager.h
@@ -0,0 +1,261 @@
+// 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 CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_
+#define CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_
+
+#include <map>
+
+#include "base/atomic_sequence_num.h"
+#include "base/debug/task_annotator.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/pending_task.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
+#include "components/scheduler/base/task_queue_impl.h"
+#include "components/scheduler/base/task_queue_selector.h"
+#include "components/scheduler/scheduler_export.h"
+
+namespace base {
+class TickClock;
+
+namespace trace_event {
+class ConvertableToTraceFormat;
+class TracedValue;
+} // namespace trace_event
+} // namespace base
+
+namespace scheduler {
+namespace internal {
+class LazyNow;
+class TaskQueueImpl;
+} // namespace internal
+
+class NestableSingleThreadTaskRunner;
+
+// The task queue manager provides N task queues and a selector interface for
+// choosing which task queue to service next. Each task queue consists of two
+// sub queues:
+//
+// 1. Incoming task queue. Tasks that are posted get immediately appended here.
+// When a task is appended into an empty incoming queue, the task manager
+// work function (DoWork) is scheduled to run on the main task runner.
+//
+// 2. Work queue. If a work queue is empty when DoWork() is entered, tasks from
+// the incoming task queue (if any) are moved here. The work queues are
+// registered with the selector as input to the scheduling decision.
+//
+class SCHEDULER_EXPORT TaskQueueManager
+ : public internal::TaskQueueSelector::Observer {
+ public:
+ // Create a task queue manager where |main_task_runner| identifies the thread
+ // on which where the tasks are eventually run. Category strings must have
+ // application lifetime (statics or literals). They may not include " chars.
+ TaskQueueManager(
+ scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
+ const char* disabled_by_default_tracing_category,
+ const char* disabled_by_default_verbose_tracing_category);
+ ~TaskQueueManager() override;
+
+ // Returns the time of the next pending delayed task in any queue. Ignores
+ // any delayed tasks whose delay has expired. Returns a null TimeTicks object
+ // if no tasks are pending. NOTE this is somewhat expensive since every queue
+ // will get locked.
+ base::TimeTicks NextPendingDelayedTaskRunTime();
+
+ // Set the number of tasks executed in a single invocation of the task queue
+ // manager. Increasing the batch size can reduce the overhead of yielding
+ // back to the main message loop -- at the cost of potentially delaying other
+ // tasks posted to the main loop. The batch size is 1 by default.
+ void SetWorkBatchSize(int work_batch_size);
+
+ // These functions can only be called on the same thread that the task queue
+ // manager executes its tasks on.
+ void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer);
+ void RemoveTaskObserver(base::MessageLoop::TaskObserver* task_observer);
+
+ void SetTimeSourceForTesting(scoped_ptr<base::TickClock> time_source);
+
+ // Returns true if any task from a monitored task queue was was run since the
+ // last call to GetAndClearSystemIsQuiescentBit.
+ bool GetAndClearSystemIsQuiescentBit();
+
+ // Creates a task queue with the given |spec|. Must be called on the thread
+ // this class was created on.
+ scoped_refptr<internal::TaskQueueImpl> NewTaskQueue(
+ const TaskQueue::Spec& spec);
+
+ class SCHEDULER_EXPORT Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Called when |queue| is unregistered.
+ virtual void OnUnregisterTaskQueue(
+ const scoped_refptr<internal::TaskQueueImpl>& queue) = 0;
+ };
+
+ // Called once to set the Observer. This function is called on the main
+ // thread. If |observer| is null, then no callbacks will occur.
+ // Note |observer| is expected to outlive the SchedulerHelper.
+ void SetObserver(Observer* observer);
+
+ private:
+ friend class internal::LazyNow;
+ friend class internal::TaskQueueImpl;
+ friend class TaskQueueManagerTest;
+
+ class DeletionSentinel : public base::RefCounted<DeletionSentinel> {
+ private:
+ friend class base::RefCounted<DeletionSentinel>;
+ ~DeletionSentinel() {}
+ };
+
+ // Unregisters a TaskQueue previously created by |NewTaskQueue()|.
+ // NOTE we have to flush the queue from |newly_updatable_| which means as a
+ // side effect MoveNewlyUpdatableQueuesIntoUpdatableQueueSet is called by this
+ // function.
+ void UnregisterTaskQueue(scoped_refptr<internal::TaskQueueImpl> task_queue);
+
+ // TaskQueueSelector::Observer implementation:
+ void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) override;
+
+ // Called by the task queue to register a new pending task.
+ void DidQueueTask(const internal::TaskQueueImpl::Task& pending_task);
+
+ // Post a task to call DoWork() on the main task runner. Only one pending
+ // DoWork is allowed from the main thread, to prevent an explosion of pending
+ // DoWorks.
+ void MaybePostDoWorkOnMainRunner();
+
+ // Use the selector to choose a pending task and run it.
+ void DoWork(bool decrement_pending_dowork_count);
+
+ // Delayed Tasks with run_times <= Now() are enqueued onto the work queue.
+ // Reloads any empty work queues which have automatic pumping enabled and
+ // which are eligible to be auto pumped based on the |previous_task| which was
+ // run and |should_trigger_wakeup|. Call with an empty |previous_task| if no
+ // task was just run.
+ void UpdateWorkQueues(bool should_trigger_wakeup,
+ const internal::TaskQueueImpl::Task* previous_task);
+
+ // Chooses the next work queue to service. Returns true if |out_queue|
+ // indicates the queue from which the next task should be run, false to
+ // avoid running any tasks.
+ bool SelectQueueToService(internal::TaskQueueImpl** out_queue);
+
+ // Runs a single nestable task from the |queue|. On exit, |out_task| will
+ // contain the task which was executed. Non-nestable task are reposted on the
+ // run loop. The queue must not be empty.
+ enum class ProcessTaskResult {
+ DEFERRED,
+ EXECUTED,
+ TASK_QUEUE_MANAGER_DELETED
+ };
+ ProcessTaskResult ProcessTaskFromWorkQueue(
+ internal::TaskQueueImpl* queue,
+ internal::TaskQueueImpl::Task* out_previous_task);
+
+ bool RunsTasksOnCurrentThread() const;
+ bool PostDelayedTask(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay);
+ bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay);
+
+ base::TimeTicks Now() const;
+
+ int GetNextSequenceNumber();
+
+ scoped_refptr<base::trace_event::ConvertableToTraceFormat>
+ AsValueWithSelectorResult(bool should_run,
+ internal::TaskQueueImpl* selected_queue) const;
+
+ // Causes DoWork to start calling UpdateWorkQueue for |queue|. Can be called
+ // from any thread.
+ void RegisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue);
+
+ // Prevents DoWork from calling UpdateWorkQueue for |queue|. Must be called
+ // from the thread the TaskQueueManager was created on.
+ void UnregisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue);
+
+ // Schedule a call to DelayedDoWork at |delayed_run_time| which will call
+ // TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue for |queue|.
+ // Can be called from any thread.
+ void ScheduleDelayedWork(internal::TaskQueueImpl* queue,
+ base::TimeTicks delayed_run_time,
+ internal::LazyNow* lazy_now);
+
+ // Function calling ScheduleDelayedWork that's suitable for use in base::Bind.
+ void ScheduleDelayedWorkTask(scoped_refptr<internal::TaskQueueImpl> queue,
+ base::TimeTicks delayed_run_time);
+
+ // Calls WakeupReadyDelayedQueues followed by DoWork so that ready delayed
+ // tasks are enqueued and run. Must be called from the main thread.
+ void DelayedDoWork();
+
+ // Call TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue for each
+ // registered queue for which the delay has elapsed.
+ void WakeupReadyDelayedQueues(internal::LazyNow* lazy_now);
+
+ void MoveNewlyUpdatableQueuesIntoUpdatableQueueSet();
+
+ std::set<scoped_refptr<internal::TaskQueueImpl>> queues_;
+
+ // We have to be careful when deleting a queue because some of the code uses
+ // raw pointers and doesn't expect the rug to be pulled out from underneath.
+ std::set<scoped_refptr<internal::TaskQueueImpl>> queues_to_delete_;
+
+ // This lock guards only |newly_updatable_|. It's not expected to be heavily
+ // contended.
+ base::Lock newly_updatable_lock_;
+ std::vector<internal::TaskQueueImpl*> newly_updatable_;
+
+ // Set of task queues with avaliable work on the incoming queue. This should
+ // only be accessed from the main thread.
+ std::set<internal::TaskQueueImpl*> updatable_queue_set_;
+
+ typedef std::multimap<base::TimeTicks, internal::TaskQueueImpl*>
+ DelayedWakeupMultimap;
+
+ DelayedWakeupMultimap delayed_wakeup_map_;
+
+ base::AtomicSequenceNumber task_sequence_num_;
+ base::debug::TaskAnnotator task_annotator_;
+
+ base::ThreadChecker main_thread_checker_;
+ scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner_;
+ internal::TaskQueueSelector selector_;
+
+ base::Closure do_work_from_main_thread_closure_;
+ base::Closure do_work_from_other_thread_closure_;
+ base::Closure delayed_queue_wakeup_closure_;
+
+ bool task_was_run_on_quiescence_monitored_queue_;
+
+ // The pending_dowork_count_ is only tracked on the main thread since that's
+ // where re-entrant problems happen.
+ int pending_dowork_count_;
+
+ int work_batch_size_;
+
+ scoped_ptr<base::TickClock> time_source_;
+
+ base::ObserverList<base::MessageLoop::TaskObserver> task_observers_;
+
+ const char* disabled_by_default_tracing_category_;
+ const char* disabled_by_default_verbose_tracing_category_;
+
+ Observer* observer_; // NOT OWNED
+ scoped_refptr<DeletionSentinel> deletion_sentinel_;
+ base::WeakPtrFactory<TaskQueueManager> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskQueueManager);
+};
+
+} // namespace scheduler
+
+#endif // CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_
diff --git a/chromium/components/scheduler/child/task_queue_manager_perftest.cc b/chromium/components/scheduler/base/task_queue_manager_perftest.cc
index 32799178039..41380baf6c5 100644
--- a/chromium/components/scheduler/child/task_queue_manager_perftest.cc
+++ b/chromium/components/scheduler/base/task_queue_manager_perftest.cc
@@ -2,59 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/scheduler/child/task_queue_manager.h"
+#include "components/scheduler/base/task_queue_manager.h"
#include "base/bind.h"
#include "base/threading/thread.h"
-#include "components/scheduler/child/scheduler_message_loop_delegate.h"
-#include "components/scheduler/child/task_queue.h"
-#include "components/scheduler/child/task_queue_selector.h"
+#include "components/scheduler/base/nestable_task_runner_for_test.h"
+#include "components/scheduler/base/task_queue_impl.h"
+#include "components/scheduler/base/task_queue_selector.h"
+#include "components/scheduler/base/task_queue_sets.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"
namespace scheduler {
-namespace {
-
-class SelectorForTest : public TaskQueueSelector {
- public:
- SelectorForTest() {}
-
- void RegisterWorkQueues(
- const std::vector<const base::TaskQueue*>& work_queues) override {
- work_queues_ = work_queues;
- }
-
- bool SelectWorkQueueToService(size_t* out_queue_index) override {
- // Choose the oldest task, if any.
- bool found_one = false;
- for (size_t i = 0; i < work_queues_.size(); i++) {
- if (work_queues_[i]->empty())
- continue;
- // Note: the < comparison is correct due to the fact that the PendingTask
- // operator inverts its comparison operation in order to work well in a
- // heap based priority queue.
- if (!found_one ||
- work_queues_[*out_queue_index]->front() < work_queues_[i]->front())
- *out_queue_index = i;
- found_one = true;
- }
- CHECK(found_one);
- return found_one;
- }
-
- void SetTaskQueueSelectorObserver(Observer* observer) override {}
-
- void AsValueInto(base::trace_event::TracedValue* state) const override {}
-
- private:
- std::vector<const base::TaskQueue*> work_queues_;
-
- DISALLOW_COPY_AND_ASSIGN(SelectorForTest);
-};
-
-} // namespace
-
class TaskQueueManagerPerfTest : public testing::Test {
public:
TaskQueueManagerPerfTest()
@@ -67,10 +27,11 @@ class TaskQueueManagerPerfTest : public testing::Test {
void Initialize(size_t num_queues) {
num_queues_ = num_queues;
message_loop_.reset(new base::MessageLoop());
- selector_ = make_scoped_ptr(new SelectorForTest);
manager_ = make_scoped_ptr(new TaskQueueManager(
- num_queues, SchedulerMessageLoopDelegate::Create(message_loop_.get()),
- selector_.get(), "fake.category", "fake.category.debug"));
+ NestableTaskRunnerForTest::Create(message_loop_->task_runner()),
+ "fake.category", "fake.category.debug"));
+ for (size_t i = 0; i < num_queues; i++)
+ queues_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test")));
}
void TestDelayedTask() {
@@ -89,7 +50,7 @@ class TaskQueueManagerPerfTest : public testing::Test {
num_tasks_to_post_ % 2 ? lower_num_tasks_to_post : 10;
for (unsigned int i = 0;
i < max_tasks_to_post && num_tasks_in_flight_ < max_tasks_in_flight_ &&
- num_tasks_to_post_ > 0;
+ num_tasks_to_post_ > 0;
i++) {
// Choose a queue weighted towards queue 0.
unsigned int queue = num_tasks_to_post_ % (num_queues_ + 1);
@@ -99,9 +60,7 @@ class TaskQueueManagerPerfTest : public testing::Test {
// Simulate a mix of short and longer delays.
unsigned int delay =
num_tasks_to_post_ % 2 ? 1 : (10 + num_tasks_to_post_ % 10);
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(queue);
- runner->PostDelayedTask(
+ queues_[queue]->PostDelayedTask(
FROM_HERE, base::Bind(&TaskQueueManagerPerfTest::TestDelayedTask,
base::Unretained(this)),
base::TimeDelta::FromMicroseconds(delay));
@@ -118,13 +77,13 @@ class TaskQueueManagerPerfTest : public testing::Test {
}
void Benchmark(const std::string& trace, const base::Closure& test_task) {
- base::TimeTicks start = base::TimeTicks::Now();
- base::TimeTicks now;
+ base::ThreadTicks start = base::ThreadTicks::Now();
+ base::ThreadTicks now;
unsigned long long num_iterations = 0;
do {
test_task.Run();
message_loop_->Run();
- now = base::TimeTicks::Now();
+ now = base::ThreadTicks::Now();
num_iterations++;
} while (now - start < base::TimeDelta::FromSeconds(5));
perf_test::PrintResult(
@@ -138,12 +97,14 @@ class TaskQueueManagerPerfTest : public testing::Test {
unsigned int num_tasks_in_flight_;
unsigned int num_tasks_to_post_;
unsigned int num_tasks_to_run_;
- scoped_ptr<SelectorForTest> selector_;
scoped_ptr<TaskQueueManager> manager_;
scoped_ptr<base::MessageLoop> message_loop_;
+ std::vector<scoped_refptr<base::SingleThreadTaskRunner>> queues_;
};
TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_OneQueue) {
+ if (!base::ThreadTicks::IsSupported())
+ return;
Initialize(1u);
max_tasks_in_flight_ = 200;
@@ -153,6 +114,8 @@ TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_OneQueue) {
}
TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_FourQueues) {
+ if (!base::ThreadTicks::IsSupported())
+ return;
Initialize(4u);
max_tasks_in_flight_ = 200;
@@ -162,6 +125,8 @@ TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_FourQueues) {
}
TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_EightQueues) {
+ if (!base::ThreadTicks::IsSupported())
+ return;
Initialize(8u);
max_tasks_in_flight_ = 200;
diff --git a/chromium/components/scheduler/base/task_queue_manager_unittest.cc b/chromium/components/scheduler/base/task_queue_manager_unittest.cc
new file mode 100644
index 00000000000..f7ccc0292c9
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_manager_unittest.cc
@@ -0,0 +1,1309 @@
+// 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/scheduler/base/task_queue_manager.h"
+
+#include "base/location.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/test/simple_test_tick_clock.h"
+#include "base/threading/thread.h"
+#include "cc/test/ordered_simple_task_runner.h"
+#include "components/scheduler/base/nestable_task_runner_for_test.h"
+#include "components/scheduler/base/task_queue_impl.h"
+#include "components/scheduler/base/task_queue_selector.h"
+#include "components/scheduler/base/task_queue_sets.h"
+#include "components/scheduler/base/test_always_fail_time_source.h"
+#include "components/scheduler/base/test_time_source.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::ElementsAre;
+using testing::_;
+
+namespace scheduler {
+
+class MessageLoopTaskRunner : public NestableTaskRunnerForTest {
+ public:
+ static scoped_refptr<MessageLoopTaskRunner> Create() {
+ return make_scoped_refptr(new MessageLoopTaskRunner());
+ }
+
+ // NestableTaskRunner implementation.
+ bool IsNested() const override {
+ return base::MessageLoop::current()->IsNested();
+ }
+
+ private:
+ MessageLoopTaskRunner()
+ : NestableTaskRunnerForTest(base::MessageLoop::current()->task_runner()) {
+ }
+ ~MessageLoopTaskRunner() override {}
+};
+
+class TaskQueueManagerTest : public testing::Test {
+ public:
+ void DeleteTaskQueueManager() { manager_.reset(); }
+
+ protected:
+ void Initialize(size_t num_queues) {
+ now_src_.reset(new base::SimpleTestTickClock());
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(1000));
+ test_task_runner_ = make_scoped_refptr(
+ new cc::OrderedSimpleTaskRunner(now_src_.get(), false));
+ main_task_runner_ =
+ NestableTaskRunnerForTest::Create(test_task_runner_.get());
+ manager_ = make_scoped_ptr(new TaskQueueManager(
+ main_task_runner_, "test.scheduler", "test.scheduler.debug"));
+ manager_->SetTimeSourceForTesting(
+ make_scoped_ptr(new TestTimeSource(now_src_.get())));
+
+ for (size_t i = 0; i < num_queues; i++)
+ runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue")));
+ }
+
+ void InitializeWithRealMessageLoop(size_t num_queues) {
+ message_loop_.reset(new base::MessageLoop());
+ manager_ = make_scoped_ptr(
+ new TaskQueueManager(MessageLoopTaskRunner::Create(), "test.scheduler",
+ "test.scheduler.debug"));
+
+ for (size_t i = 0; i < num_queues; i++)
+ runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue")));
+ }
+
+ scoped_ptr<base::MessageLoop> message_loop_;
+ scoped_ptr<base::SimpleTestTickClock> now_src_;
+ scoped_refptr<NestableTaskRunnerForTest> main_task_runner_;
+ scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner_;
+ scoped_ptr<TaskQueueManager> manager_;
+ std::vector<scoped_refptr<internal::TaskQueueImpl>> runners_;
+};
+
+void PostFromNestedRunloop(base::MessageLoop* message_loop,
+ base::SingleThreadTaskRunner* runner,
+ std::vector<std::pair<base::Closure, bool>>* tasks) {
+ base::MessageLoop::ScopedNestableTaskAllower allow(message_loop);
+ for (std::pair<base::Closure, bool>& pair : *tasks) {
+ if (pair.second) {
+ runner->PostTask(FROM_HERE, pair.first);
+ } else {
+ runner->PostNonNestableTask(FROM_HERE, pair.first);
+ }
+ }
+ message_loop->RunUntilIdle();
+}
+
+void NullTask() {}
+
+void TestTask(int value, std::vector<int>* out_result) {
+ out_result->push_back(value);
+}
+
+TEST_F(TaskQueueManagerTest, SingleQueuePosting) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
+}
+
+TEST_F(TaskQueueManagerTest, MultiQueuePosting) {
+ Initialize(3u);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
+ runners_[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order));
+ runners_[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order));
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5, 6));
+}
+
+void NopTask() {}
+
+TEST_F(TaskQueueManagerTest, NowNotCalledWhenThereAreNoDelayedTasks) {
+ Initialize(3u);
+
+ manager_->SetTimeSourceForTesting(
+ make_scoped_ptr(new TestAlwaysFailTimeSource()));
+
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
+ runners_[2]->PostTask(FROM_HERE, base::Bind(&NopTask));
+ runners_[2]->PostTask(FROM_HERE, base::Bind(&NopTask));
+
+ test_task_runner_->RunUntilIdle();
+}
+
+TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) {
+ InitializeWithRealMessageLoop(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->PostNonNestableTask(FROM_HERE,
+ base::Bind(&TestTask, 1, &run_order));
+
+ message_loop_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1));
+}
+
+TEST_F(TaskQueueManagerTest, NonNestableTaskExecutesInExpectedOrder) {
+ InitializeWithRealMessageLoop(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
+ runners_[0]->PostNonNestableTask(FROM_HERE,
+ base::Bind(&TestTask, 5, &run_order));
+
+ message_loop_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5));
+}
+
+TEST_F(TaskQueueManagerTest, NonNestableTaskDoesntExecuteInNestedLoop) {
+ InitializeWithRealMessageLoop(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+
+ std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
+ tasks_to_post_from_nested_loop.push_back(
+ std::make_pair(base::Bind(&TestTask, 3, &run_order), false));
+ tasks_to_post_from_nested_loop.push_back(
+ std::make_pair(base::Bind(&TestTask, 4, &run_order), true));
+ tasks_to_post_from_nested_loop.push_back(
+ std::make_pair(base::Bind(&TestTask, 5, &run_order), true));
+
+ runners_[0]->PostTask(
+ FROM_HERE,
+ base::Bind(&PostFromNestedRunloop, message_loop_.get(), runners_[0],
+ base::Unretained(&tasks_to_post_from_nested_loop)));
+
+ message_loop_->RunUntilIdle();
+ // Note we expect task 3 to run last because it's non-nestable.
+ EXPECT_THAT(run_order, ElementsAre(1, 2, 4, 5, 3));
+}
+
+TEST_F(TaskQueueManagerTest, QueuePolling) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ EXPECT_TRUE(runners_[0]->IsQueueEmpty());
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ EXPECT_FALSE(runners_[0]->IsQueueEmpty());
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(runners_[0]->IsQueueEmpty());
+}
+
+TEST_F(TaskQueueManagerTest, DelayedTaskPosting) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ delay);
+ EXPECT_EQ(delay, test_task_runner_->DelayToNextTaskTime());
+ EXPECT_TRUE(runners_[0]->IsQueueEmpty());
+ EXPECT_TRUE(run_order.empty());
+
+ // The task doesn't run before the delay has completed.
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(9));
+ EXPECT_TRUE(run_order.empty());
+
+ // After the delay has completed, the task runs normally.
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
+ EXPECT_THAT(run_order, ElementsAre(1));
+}
+
+bool MessageLoopTaskCounter(size_t* count) {
+ *count = *count + 1;
+ return true;
+}
+
+TEST_F(TaskQueueManagerTest, DelayedTaskExecutedInOneMessageLoopTask) {
+ Initialize(1u);
+
+ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay);
+
+ size_t task_count = 0;
+ test_task_runner_->RunTasksWhile(
+ base::Bind(&MessageLoopTaskCounter, &task_count));
+ EXPECT_EQ(1u, task_count);
+}
+
+TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ base::TimeDelta::FromMilliseconds(10));
+
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
+ base::TimeDelta::FromMilliseconds(8));
+
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
+ base::TimeDelta::FromMilliseconds(5));
+
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(5),
+ test_task_runner_->DelayToNextTaskTime());
+
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
+ EXPECT_THAT(run_order, ElementsAre(3));
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(3),
+ test_task_runner_->DelayToNextTaskTime());
+
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(3));
+ EXPECT_THAT(run_order, ElementsAre(3, 2));
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(2),
+ test_task_runner_->DelayToNextTaskTime());
+
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(2));
+ EXPECT_THAT(run_order, ElementsAre(3, 2, 1));
+}
+
+TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ base::TimeDelta::FromMilliseconds(1));
+
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
+ base::TimeDelta::FromMilliseconds(5));
+
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
+ base::TimeDelta::FromMilliseconds(10));
+
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(1),
+ test_task_runner_->DelayToNextTaskTime());
+
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
+ EXPECT_THAT(run_order, ElementsAre(1));
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(4),
+ test_task_runner_->DelayToNextTaskTime());
+
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(4));
+ EXPECT_THAT(run_order, ElementsAre(1, 2));
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(5),
+ test_task_runner_->DelayToNextTaskTime());
+
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
+ EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
+}
+
+TEST_F(TaskQueueManagerTest, PostDelayedTask_SharesUnderlyingDelayedTasks) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ delay);
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
+ delay);
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
+ delay);
+
+ EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
+}
+
+class TestObject {
+ public:
+ ~TestObject() { destructor_count_++; }
+
+ void Run() { FAIL() << "TestObject::Run should not be called"; }
+
+ static int destructor_count_;
+};
+
+int TestObject::destructor_count_ = 0;
+
+TEST_F(TaskQueueManagerTest, PendingDelayedTasksRemovedOnShutdown) {
+ Initialize(1u);
+
+ TestObject::destructor_count_ = 0;
+
+ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
+ runners_[0]->PostDelayedTask(
+ FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())),
+ delay);
+ runners_[0]->PostTask(
+ FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())));
+
+ manager_.reset();
+
+ EXPECT_EQ(2, TestObject::destructor_count_);
+}
+
+TEST_F(TaskQueueManagerTest, ManualPumping) {
+ Initialize(1u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
+
+ std::vector<int> run_order;
+ // Posting a task when pumping is disabled doesn't result in work getting
+ // posted.
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ EXPECT_FALSE(test_task_runner_->HasPendingTasks());
+
+ // However polling still works.
+ EXPECT_FALSE(runners_[0]->IsQueueEmpty());
+
+ // After pumping the task runs normally.
+ runners_[0]->PumpQueue();
+ EXPECT_TRUE(test_task_runner_->HasPendingTasks());
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1));
+}
+
+TEST_F(TaskQueueManagerTest, ManualPumpingToggle) {
+ Initialize(1u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
+
+ std::vector<int> run_order;
+ // Posting a task when pumping is disabled doesn't result in work getting
+ // posted.
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ EXPECT_FALSE(test_task_runner_->HasPendingTasks());
+
+ // When pumping is enabled the task runs normally.
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
+ EXPECT_TRUE(test_task_runner_->HasPendingTasks());
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1));
+}
+
+TEST_F(TaskQueueManagerTest, DenyRunning_BeforePosting) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->SetQueuePriority(TaskQueue::DISABLED_PRIORITY);
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(run_order.empty());
+
+ runners_[0]->SetQueuePriority(TaskQueue::NORMAL_PRIORITY);
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1));
+}
+
+TEST_F(TaskQueueManagerTest, DenyRunning_AfterPosting) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ runners_[0]->SetQueuePriority(TaskQueue::DISABLED_PRIORITY);
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(run_order.empty());
+
+ runners_[0]->SetQueuePriority(TaskQueue::NORMAL_PRIORITY);
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1));
+}
+
+TEST_F(TaskQueueManagerTest, DenyRunning_ManuallyPumpedTransitionsToAuto) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
+ runners_[0]->SetQueuePriority(TaskQueue::DISABLED_PRIORITY);
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(run_order.empty());
+
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
+ runners_[0]->SetQueuePriority(TaskQueue::NORMAL_PRIORITY);
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1));
+}
+
+TEST_F(TaskQueueManagerTest, ManualPumpingWithDelayedTask) {
+ Initialize(1u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
+
+ std::vector<int> run_order;
+ // Posting a delayed task when pumping will apply the delay, but won't cause
+ // work to executed afterwards.
+ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ delay);
+
+ // After pumping but before the delay period has expired, task does not run.
+ runners_[0]->PumpQueue();
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
+ EXPECT_TRUE(run_order.empty());
+
+ // Once the delay has expired, pumping causes the task to run.
+ now_src_->Advance(base::TimeDelta::FromMilliseconds(5));
+ runners_[0]->PumpQueue();
+ EXPECT_TRUE(test_task_runner_->HasPendingTasks());
+ test_task_runner_->RunPendingTasks();
+ EXPECT_THAT(run_order, ElementsAre(1));
+}
+
+TEST_F(TaskQueueManagerTest, ManualPumpingWithMultipleDelayedTasks) {
+ Initialize(1u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
+
+ std::vector<int> run_order;
+ // Posting a delayed task when pumping will apply the delay, but won't cause
+ // work to executed afterwards.
+ base::TimeDelta delay1(base::TimeDelta::FromMilliseconds(1));
+ base::TimeDelta delay2(base::TimeDelta::FromMilliseconds(10));
+ base::TimeDelta delay3(base::TimeDelta::FromMilliseconds(20));
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ delay1);
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
+ delay2);
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
+ delay3);
+
+ now_src_->Advance(base::TimeDelta::FromMilliseconds(15));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(run_order.empty());
+
+ // Once the delay has expired, pumping causes the task to run.
+ runners_[0]->PumpQueue();
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1, 2));
+}
+
+TEST_F(TaskQueueManagerTest, DelayedTasksDontAutoRunWithManualPumping) {
+ Initialize(1u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
+
+ std::vector<int> run_order;
+ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ delay);
+
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(10));
+ EXPECT_TRUE(run_order.empty());
+}
+
+TEST_F(TaskQueueManagerTest, ManualPumpingWithNonEmptyWorkQueue) {
+ Initialize(1u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
+
+ std::vector<int> run_order;
+ // Posting two tasks and pumping twice should result in two tasks in the work
+ // queue.
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ runners_[0]->PumpQueue();
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ runners_[0]->PumpQueue();
+
+ EXPECT_EQ(2u, runners_[0]->WorkQueueSizeForTest());
+}
+
+void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
+ int countdown,
+ std::vector<int>* out_result) {
+ out_result->push_back(countdown);
+ if (--countdown) {
+ runner->PostTask(FROM_HERE,
+ Bind(&ReentrantTestTask, runner, countdown, out_result));
+ }
+}
+
+TEST_F(TaskQueueManagerTest, ReentrantPosting) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE,
+ Bind(&ReentrantTestTask, runners_[0], 3, &run_order));
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(3, 2, 1));
+}
+
+TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) {
+ Initialize(1u);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ manager_.reset();
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(run_order.empty());
+}
+
+void PostTaskToRunner(scoped_refptr<base::SingleThreadTaskRunner> runner,
+ std::vector<int>* run_order) {
+ runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, run_order));
+}
+
+TEST_F(TaskQueueManagerTest, PostFromThread) {
+ InitializeWithRealMessageLoop(1u);
+
+ std::vector<int> run_order;
+ base::Thread thread("TestThread");
+ thread.Start();
+ thread.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&PostTaskToRunner, runners_[0], &run_order));
+ thread.Stop();
+
+ message_loop_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(1));
+}
+
+void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
+ int* run_count) {
+ (*run_count)++;
+ runner->PostTask(FROM_HERE, Bind(&RePostingTestTask,
+ base::Unretained(runner.get()), run_count));
+}
+
+TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) {
+ Initialize(1u);
+
+ int run_count = 0;
+ runners_[0]->PostTask(
+ FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count));
+
+ test_task_runner_->RunPendingTasks();
+ // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there
+ // will be two tasks here.
+ EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
+ EXPECT_EQ(1, run_count);
+}
+
+TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) {
+ InitializeWithRealMessageLoop(1u);
+
+ std::vector<int> run_order;
+ std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
+ tasks_to_post_from_nested_loop.push_back(
+ std::make_pair(base::Bind(&TestTask, 1, &run_order), true));
+
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 0, &run_order));
+ runners_[0]->PostTask(
+ FROM_HERE,
+ base::Bind(&PostFromNestedRunloop, message_loop_.get(), runners_[0],
+ base::Unretained(&tasks_to_post_from_nested_loop)));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+
+ message_loop_->RunUntilIdle();
+
+ EXPECT_THAT(run_order, ElementsAre(0, 2, 1));
+}
+
+TEST_F(TaskQueueManagerTest, WorkBatching) {
+ Initialize(1u);
+
+ manager_->SetWorkBatchSize(2);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
+
+ // Running one task in the host message loop should cause two posted tasks to
+ // get executed.
+ EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u);
+ test_task_runner_->RunPendingTasks();
+ EXPECT_THAT(run_order, ElementsAre(1, 2));
+
+ // The second task runs the remaining two posted tasks.
+ EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u);
+ test_task_runner_->RunPendingTasks();
+ EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4));
+}
+
+TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeup) {
+ Initialize(2u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM.
+
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(run_order.empty()); // Still shouldn't wake TQM.
+
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+ test_task_runner_->RunUntilIdle();
+ // Executing a task on an auto pumped queue should wake the TQM.
+ EXPECT_THAT(run_order, ElementsAre(3, 1, 2));
+}
+
+TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWhenAlreadyAwake) {
+ Initialize(2u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(2, 1)); // TQM was already awake.
+}
+
+TEST_F(TaskQueueManagerTest,
+ AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue) {
+ Initialize(2u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
+ runners_[1]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM.
+
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ test_task_runner_->RunUntilIdle();
+ // This still shouldn't wake TQM as manual queue was not pumped.
+ EXPECT_TRUE(run_order.empty());
+
+ runners_[1]->PumpQueue();
+ test_task_runner_->RunUntilIdle();
+ // Executing a task on an auto pumped queue should wake the TQM.
+ EXPECT_THAT(run_order, ElementsAre(2, 1));
+}
+
+void TestPostingTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ base::Closure task) {
+ task_runner->PostTask(FROM_HERE, task);
+}
+
+TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromTask) {
+ Initialize(2u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
+
+ std::vector<int> run_order;
+ // Check that a task which posts a task to an auto pump after wakeup queue
+ // doesn't cause the queue to wake up.
+ base::Closure after_wakeup_task = base::Bind(&TestTask, 1, &run_order);
+ runners_[1]->PostTask(
+ FROM_HERE, base::Bind(&TestPostingTask, runners_[0], after_wakeup_task));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(run_order.empty());
+
+ // Wake up the queue.
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(2, 1));
+}
+
+TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromMultipleTasks) {
+ Initialize(2u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
+
+ std::vector<int> run_order;
+ // Check that a task which posts a task to an auto pump after wakeup queue
+ // doesn't cause the queue to wake up.
+ base::Closure after_wakeup_task_1 = base::Bind(&TestTask, 1, &run_order);
+ base::Closure after_wakeup_task_2 = base::Bind(&TestTask, 2, &run_order);
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestPostingTask, runners_[0],
+ after_wakeup_task_1));
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestPostingTask, runners_[0],
+ after_wakeup_task_2));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(run_order.empty());
+
+ // Wake up the queue.
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_THAT(run_order, ElementsAre(3, 1, 2));
+}
+
+TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupBecomesQuiescent) {
+ Initialize(2u);
+ runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
+
+ int run_count = 0;
+ // Check that if multiple tasks reposts themselves onto a pump-after-wakeup
+ // queue they don't wake each other and will eventually stop when no other
+ // tasks execute.
+ runners_[0]->PostTask(
+ FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count));
+ runners_[0]->PostTask(
+ FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count));
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
+ test_task_runner_->RunUntilIdle();
+ // The reposting tasks posted to the after wakeup queue shouldn't have woken
+ // each other up.
+ EXPECT_EQ(2, run_count);
+}
+
+TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWithDontWakeQueue) {
+ Initialize(1u);
+
+ scoped_refptr<internal::TaskQueueImpl> queue0 = manager_->NewTaskQueue(
+ TaskQueue::Spec("test_queue 0")
+ .SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP));
+ scoped_refptr<internal::TaskQueueImpl> queue1 = manager_->NewTaskQueue(
+ TaskQueue::Spec("test_queue 0")
+ .SetWakeupPolicy(TaskQueue::WakeupPolicy::DONT_WAKE_OTHER_QUEUES));
+ scoped_refptr<internal::TaskQueueImpl> queue2 = runners_[0];
+
+ std::vector<int> run_order;
+ queue0->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ test_task_runner_->RunUntilIdle();
+ // Executing a DONT_WAKE_OTHER_QUEUES queue shouldn't wake the autopump after
+ // wakeup queue.
+ EXPECT_THAT(run_order, ElementsAre(2));
+
+ queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+ test_task_runner_->RunUntilIdle();
+ // Executing a CAN_WAKE_OTHER_QUEUES queue should wake the autopump after
+ // wakeup queue.
+ EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
+}
+
+class MockTaskObserver : public base::MessageLoop::TaskObserver {
+ public:
+ MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task));
+ MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task));
+};
+
+TEST_F(TaskQueueManagerTest, TaskObserverAdding) {
+ InitializeWithRealMessageLoop(1u);
+ MockTaskObserver observer;
+
+ manager_->SetWorkBatchSize(2);
+ manager_->AddTaskObserver(&observer);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+
+ EXPECT_CALL(observer, WillProcessTask(_)).Times(2);
+ EXPECT_CALL(observer, DidProcessTask(_)).Times(2);
+ message_loop_->RunUntilIdle();
+}
+
+TEST_F(TaskQueueManagerTest, TaskObserverRemoving) {
+ InitializeWithRealMessageLoop(1u);
+ MockTaskObserver observer;
+ manager_->SetWorkBatchSize(2);
+ manager_->AddTaskObserver(&observer);
+ manager_->RemoveTaskObserver(&observer);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+
+ EXPECT_CALL(observer, WillProcessTask(_)).Times(0);
+ EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
+
+ message_loop_->RunUntilIdle();
+}
+
+void RemoveObserverTask(TaskQueueManager* manager,
+ base::MessageLoop::TaskObserver* observer) {
+ manager->RemoveTaskObserver(observer);
+}
+
+TEST_F(TaskQueueManagerTest, TaskObserverRemovingInsideTask) {
+ InitializeWithRealMessageLoop(1u);
+ MockTaskObserver observer;
+ manager_->SetWorkBatchSize(3);
+ manager_->AddTaskObserver(&observer);
+
+ runners_[0]->PostTask(
+ FROM_HERE, base::Bind(&RemoveObserverTask, manager_.get(), &observer));
+
+ EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
+ EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
+ message_loop_->RunUntilIdle();
+}
+
+TEST_F(TaskQueueManagerTest, QueueTaskObserverAdding) {
+ InitializeWithRealMessageLoop(2u);
+ MockTaskObserver observer;
+
+ manager_->SetWorkBatchSize(2);
+ runners_[0]->AddTaskObserver(&observer);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+
+ EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
+ EXPECT_CALL(observer, DidProcessTask(_)).Times(1);
+ message_loop_->RunUntilIdle();
+}
+
+TEST_F(TaskQueueManagerTest, QueueTaskObserverRemoving) {
+ InitializeWithRealMessageLoop(1u);
+ MockTaskObserver observer;
+ manager_->SetWorkBatchSize(2);
+ runners_[0]->AddTaskObserver(&observer);
+ runners_[0]->RemoveTaskObserver(&observer);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+
+ EXPECT_CALL(observer, WillProcessTask(_)).Times(0);
+ EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
+
+ message_loop_->RunUntilIdle();
+}
+
+void RemoveQueueObserverTask(scoped_refptr<TaskQueue> queue,
+ base::MessageLoop::TaskObserver* observer) {
+ queue->RemoveTaskObserver(observer);
+}
+
+TEST_F(TaskQueueManagerTest, QueueTaskObserverRemovingInsideTask) {
+ InitializeWithRealMessageLoop(1u);
+ MockTaskObserver observer;
+ runners_[0]->AddTaskObserver(&observer);
+
+ runners_[0]->PostTask(
+ FROM_HERE, base::Bind(&RemoveQueueObserverTask, runners_[0], &observer));
+
+ EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
+ EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
+ message_loop_->RunUntilIdle();
+}
+
+TEST_F(TaskQueueManagerTest, ThreadCheckAfterTermination) {
+ Initialize(1u);
+ EXPECT_TRUE(runners_[0]->RunsTasksOnCurrentThread());
+ manager_.reset();
+ EXPECT_TRUE(runners_[0]->RunsTasksOnCurrentThread());
+}
+
+TEST_F(TaskQueueManagerTest, NextPendingDelayedTaskRunTime) {
+ scoped_ptr<base::SimpleTestTickClock> clock(new base::SimpleTestTickClock());
+ clock->Advance(base::TimeDelta::FromMicroseconds(10000));
+ Initialize(2u);
+ manager_->SetTimeSourceForTesting(
+ make_scoped_ptr(new TestTimeSource(clock.get())));
+
+ // With no delayed tasks.
+ EXPECT_TRUE(manager_->NextPendingDelayedTaskRunTime().is_null());
+
+ // With a non-delayed task.
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
+ EXPECT_TRUE(manager_->NextPendingDelayedTaskRunTime().is_null());
+
+ // With a delayed task.
+ base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(50);
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
+ EXPECT_EQ(clock->NowTicks() + expected_delay,
+ manager_->NextPendingDelayedTaskRunTime());
+
+ // With another delayed task in the same queue with a longer delay.
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask),
+ base::TimeDelta::FromMilliseconds(100));
+ EXPECT_EQ(clock->NowTicks() + expected_delay,
+ manager_->NextPendingDelayedTaskRunTime());
+
+ // With another delayed task in the same queue with a shorter delay.
+ expected_delay = base::TimeDelta::FromMilliseconds(20);
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
+ EXPECT_EQ(clock->NowTicks() + expected_delay,
+ manager_->NextPendingDelayedTaskRunTime());
+
+ // With another delayed task in a different queue with a shorter delay.
+ expected_delay = base::TimeDelta::FromMilliseconds(10);
+ runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
+ EXPECT_EQ(clock->NowTicks() + expected_delay,
+ manager_->NextPendingDelayedTaskRunTime());
+
+ // Test it updates as time progresses
+ clock->Advance(expected_delay);
+ EXPECT_EQ(clock->NowTicks(), manager_->NextPendingDelayedTaskRunTime());
+}
+
+TEST_F(TaskQueueManagerTest, NextPendingDelayedTaskRunTime_MultipleQueues) {
+ Initialize(3u);
+
+ base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50);
+ base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5);
+ base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(10);
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay1);
+ runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay2);
+ runners_[2]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay3);
+
+ EXPECT_EQ(now_src_->NowTicks() + delay2,
+ manager_->NextPendingDelayedTaskRunTime());
+}
+
+TEST_F(TaskQueueManagerTest, DeleteTaskQueueManagerInsideATask) {
+ Initialize(1u);
+
+ runners_[0]->PostTask(
+ FROM_HERE, base::Bind(&TaskQueueManagerTest::DeleteTaskQueueManager,
+ base::Unretained(this)));
+
+ // This should not crash, assuming DoWork detects the TaskQueueManager has
+ // been deleted.
+ test_task_runner_->RunUntilIdle();
+}
+
+TEST_F(TaskQueueManagerTest, GetAndClearSystemIsQuiescentBit) {
+ Initialize(3u);
+
+ scoped_refptr<internal::TaskQueueImpl> queue0 = manager_->NewTaskQueue(
+ TaskQueue::Spec("test_queue 0").SetShouldMonitorQuiescence(true));
+ scoped_refptr<internal::TaskQueueImpl> queue1 = manager_->NewTaskQueue(
+ TaskQueue::Spec("test_queue 1").SetShouldMonitorQuiescence(true));
+ scoped_refptr<internal::TaskQueueImpl> queue2 = manager_->NewTaskQueue(
+ TaskQueue::Spec("test_queue 2").SetShouldMonitorQuiescence(false));
+
+ EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
+
+ queue0->PostTask(FROM_HERE, base::Bind(&NopTask));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit());
+ EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
+
+ queue1->PostTask(FROM_HERE, base::Bind(&NopTask));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit());
+ EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
+
+ queue2->PostTask(FROM_HERE, base::Bind(&NopTask));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
+
+ queue0->PostTask(FROM_HERE, base::Bind(&NopTask));
+ queue1->PostTask(FROM_HERE, base::Bind(&NopTask));
+ test_task_runner_->RunUntilIdle();
+ EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit());
+ EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
+}
+
+TEST_F(TaskQueueManagerTest, IsQueueEmpty) {
+ Initialize(2u);
+ internal::TaskQueueImpl* queue0 = runners_[0].get();
+ internal::TaskQueueImpl* queue1 = runners_[1].get();
+ queue0->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
+ queue1->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
+
+ EXPECT_TRUE(queue0->IsQueueEmpty());
+ EXPECT_TRUE(queue1->IsQueueEmpty());
+
+ queue0->PostTask(FROM_HERE, base::Bind(NullTask));
+ queue1->PostTask(FROM_HERE, base::Bind(NullTask));
+ EXPECT_FALSE(queue0->IsQueueEmpty());
+ EXPECT_FALSE(queue1->IsQueueEmpty());
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(queue0->IsQueueEmpty());
+ EXPECT_FALSE(queue1->IsQueueEmpty());
+
+ queue1->PumpQueue();
+ EXPECT_TRUE(queue0->IsQueueEmpty());
+ EXPECT_FALSE(queue1->IsQueueEmpty());
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_TRUE(queue0->IsQueueEmpty());
+ EXPECT_TRUE(queue1->IsQueueEmpty());
+}
+
+TEST_F(TaskQueueManagerTest, GetQueueState) {
+ Initialize(2u);
+ internal::TaskQueueImpl* queue0 = runners_[0].get();
+ internal::TaskQueueImpl* queue1 = runners_[1].get();
+ queue0->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
+ queue1->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
+
+ EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState());
+ EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue1->GetQueueState());
+
+ queue0->PostTask(FROM_HERE, base::Bind(NullTask));
+ queue0->PostTask(FROM_HERE, base::Bind(NullTask));
+ queue1->PostTask(FROM_HERE, base::Bind(NullTask));
+ EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue0->GetQueueState());
+ EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue1->GetQueueState());
+
+ test_task_runner_->SetRunTaskLimit(1);
+ test_task_runner_->RunPendingTasks();
+ EXPECT_EQ(TaskQueue::QueueState::HAS_WORK, queue0->GetQueueState());
+ EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue1->GetQueueState());
+
+ test_task_runner_->ClearRunTaskLimit();
+ test_task_runner_->RunUntilIdle();
+ EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState());
+ EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue1->GetQueueState());
+
+ queue1->PumpQueue();
+ EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState());
+ EXPECT_EQ(TaskQueue::QueueState::HAS_WORK, queue1->GetQueueState());
+
+ test_task_runner_->RunUntilIdle();
+ EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState());
+ EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue1->GetQueueState());
+}
+
+TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfNonDelayedTask) {
+ Initialize(2u);
+
+ std::vector<int> run_order;
+ base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ delay);
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+
+ now_src_->Advance(delay * 2);
+ // After task 2 has run, the automatic selector will have to choose between
+ // tasks 1 and 3. The sequence numbers are used to choose between the two
+ // tasks and if they are correct task 1 will run last.
+ test_task_runner_->RunUntilIdle();
+
+ EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
+}
+
+TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfShorterDelayedTask) {
+ Initialize(2u);
+
+ std::vector<int> run_order;
+ base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10);
+ base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5);
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ delay1);
+ runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
+ delay2);
+
+ now_src_->Advance(delay1 * 2);
+ test_task_runner_->RunUntilIdle();
+
+ EXPECT_THAT(run_order, ElementsAre(2, 1));
+}
+
+TEST_F(TaskQueueManagerTest, DelayedTaskWithAbsoluteRunTime) {
+ Initialize(1u);
+
+ // One task in the past, two with the exact same run time and one in the
+ // future.
+ base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
+ base::TimeTicks runTime1 = now_src_->NowTicks() - delay;
+ base::TimeTicks runTime2 = now_src_->NowTicks();
+ base::TimeTicks runTime3 = now_src_->NowTicks();
+ base::TimeTicks runTime4 = now_src_->NowTicks() + delay;
+
+ std::vector<int> run_order;
+ runners_[0]->PostDelayedTaskAt(
+ FROM_HERE, base::Bind(&TestTask, 1, &run_order), runTime1);
+ runners_[0]->PostDelayedTaskAt(
+ FROM_HERE, base::Bind(&TestTask, 2, &run_order), runTime2);
+ runners_[0]->PostDelayedTaskAt(
+ FROM_HERE, base::Bind(&TestTask, 3, &run_order), runTime3);
+ runners_[0]->PostDelayedTaskAt(
+ FROM_HERE, base::Bind(&TestTask, 4, &run_order), runTime4);
+
+ now_src_->Advance(2 * delay);
+ test_task_runner_->RunUntilIdle();
+
+ EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4));
+}
+
+void CheckIsNested(bool* is_nested) {
+ *is_nested = base::MessageLoop::current()->IsNested();
+}
+
+void PostAndQuitFromNestedRunloop(base::RunLoop* run_loop,
+ base::SingleThreadTaskRunner* runner,
+ bool* was_nested) {
+ base::MessageLoop::ScopedNestableTaskAllower allow(
+ base::MessageLoop::current());
+ runner->PostTask(FROM_HERE, run_loop->QuitClosure());
+ runner->PostTask(FROM_HERE, base::Bind(&CheckIsNested, was_nested));
+ run_loop->Run();
+}
+
+TEST_F(TaskQueueManagerTest, QuitWhileNested) {
+ // This test makes sure we don't continue running a work batch after a nested
+ // run loop has been exited in the middle of the batch.
+ InitializeWithRealMessageLoop(1u);
+ manager_->SetWorkBatchSize(2);
+
+ bool was_nested = true;
+ base::RunLoop run_loop;
+ runners_[0]->PostTask(
+ FROM_HERE,
+ base::Bind(&PostAndQuitFromNestedRunloop, base::Unretained(&run_loop),
+ runners_[0], base::Unretained(&was_nested)));
+
+ message_loop_->RunUntilIdle();
+ EXPECT_FALSE(was_nested);
+}
+
+class SequenceNumberCapturingTaskObserver
+ : public base::MessageLoop::TaskObserver {
+ public:
+ // MessageLoop::TaskObserver overrides.
+ void WillProcessTask(const base::PendingTask& pending_task) override {}
+ void DidProcessTask(const base::PendingTask& pending_task) override {
+ sequence_numbers_.push_back(pending_task.sequence_num);
+ }
+
+ const std::vector<int>& sequence_numbers() const { return sequence_numbers_; }
+
+ private:
+ std::vector<int> sequence_numbers_;
+};
+
+TEST_F(TaskQueueManagerTest, SequenceNumSetWhenTaskIsPosted) {
+ Initialize(1u);
+
+ SequenceNumberCapturingTaskObserver observer;
+ manager_->AddTaskObserver(&observer);
+
+ // Register four tasks that will run in reverse order.
+ std::vector<int> run_order;
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ base::TimeDelta::FromMilliseconds(30));
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
+ base::TimeDelta::FromMilliseconds(20));
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
+ base::TimeDelta::FromMilliseconds(10));
+ runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
+
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40));
+ ASSERT_THAT(run_order, ElementsAre(4, 3, 2, 1));
+
+ // The sequence numbers are a zero-based monotonically incrememting counter
+ // which should be set when the task is posted rather than when it's enqueued
+ // onto the incomming queue.
+ EXPECT_THAT(observer.sequence_numbers(), ElementsAre(3, 2, 1, 0));
+
+ manager_->RemoveTaskObserver(&observer);
+}
+
+TEST_F(TaskQueueManagerTest, NewTaskQueues) {
+ Initialize(1u);
+
+ scoped_refptr<internal::TaskQueueImpl> queue1 =
+ manager_->NewTaskQueue(TaskQueue::Spec("foo"));
+ scoped_refptr<internal::TaskQueueImpl> queue2 =
+ manager_->NewTaskQueue(TaskQueue::Spec("bar"));
+ scoped_refptr<internal::TaskQueueImpl> queue3 =
+ manager_->NewTaskQueue(TaskQueue::Spec("baz"));
+
+ ASSERT_NE(queue1, queue2);
+ ASSERT_NE(queue1, queue3);
+ ASSERT_NE(queue2, queue3);
+
+ std::vector<int> run_order;
+ queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ queue3->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+ test_task_runner_->RunUntilIdle();
+
+ EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
+}
+
+TEST_F(TaskQueueManagerTest, UnregisterTaskQueue) {
+ Initialize(1u);
+
+ scoped_refptr<internal::TaskQueueImpl> queue1 =
+ manager_->NewTaskQueue(TaskQueue::Spec("foo"));
+ scoped_refptr<internal::TaskQueueImpl> queue2 =
+ manager_->NewTaskQueue(TaskQueue::Spec("bar"));
+ scoped_refptr<internal::TaskQueueImpl> queue3 =
+ manager_->NewTaskQueue(TaskQueue::Spec("baz"));
+
+ ASSERT_NE(queue1, queue2);
+ ASSERT_NE(queue1, queue3);
+ ASSERT_NE(queue2, queue3);
+
+ std::vector<int> run_order;
+ queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+ queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+ queue3->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+
+ queue2->UnregisterTaskQueue();
+ test_task_runner_->RunUntilIdle();
+
+ EXPECT_THAT(run_order, ElementsAre(1, 3));
+}
+
+TEST_F(TaskQueueManagerTest, UnregisterTaskQueue_WithDelayedTasks) {
+ Initialize(2u);
+
+ // Register three delayed tasks
+ std::vector<int> run_order;
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
+ base::TimeDelta::FromMilliseconds(10));
+ runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
+ base::TimeDelta::FromMilliseconds(20));
+ runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
+ base::TimeDelta::FromMilliseconds(30));
+
+ runners_[1]->UnregisterTaskQueue();
+ test_task_runner_->RunUntilIdle();
+
+ test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40));
+ ASSERT_THAT(run_order, ElementsAre(1, 3));
+}
+
+void PostTestTasksFromNestedMessageLoop(
+ base::MessageLoop* message_loop,
+ scoped_refptr<base::SingleThreadTaskRunner> main_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> wake_up_runner,
+ std::vector<int>* run_order) {
+ base::MessageLoop::ScopedNestableTaskAllower allow(message_loop);
+ main_runner->PostNonNestableTask(FROM_HERE,
+ base::Bind(&TestTask, 1, run_order));
+ // The following should never get executed.
+ wake_up_runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, run_order));
+ message_loop->RunUntilIdle();
+}
+
+TEST_F(TaskQueueManagerTest, DeferredNonNestableTaskDoesNotTriggerWakeUp) {
+ // This test checks that running (i.e., deferring) a non-nestable task in a
+ // nested run loop does not trigger the pumping of an on-wakeup queue.
+ InitializeWithRealMessageLoop(2u);
+ runners_[1]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
+
+ std::vector<int> run_order;
+ runners_[0]->PostTask(
+ FROM_HERE,
+ base::Bind(&PostTestTasksFromNestedMessageLoop, message_loop_.get(),
+ runners_[0], runners_[1], base::Unretained(&run_order)));
+
+ message_loop_->RunUntilIdle();
+ ASSERT_THAT(run_order, ElementsAre(1));
+}
+
+namespace {
+
+class MockObserver : public TaskQueueManager::Observer {
+ public:
+ MOCK_METHOD1(OnUnregisterTaskQueue,
+ void(const scoped_refptr<internal::TaskQueueImpl>& queue));
+};
+
+} // namespace
+
+TEST_F(TaskQueueManagerTest, OnUnregisterTaskQueue) {
+ Initialize(0u);
+
+ MockObserver observer;
+ manager_->SetObserver(&observer);
+
+ scoped_refptr<internal::TaskQueueImpl> task_queue =
+ manager_->NewTaskQueue(TaskQueue::Spec("test_queue"));
+
+ EXPECT_CALL(observer, OnUnregisterTaskQueue(_)).Times(1);
+ task_queue->UnregisterTaskQueue();
+
+ manager_->SetObserver(nullptr);
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_selector.cc b/chromium/components/scheduler/base/task_queue_selector.cc
new file mode 100644
index 00000000000..0b65ec3d504
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_selector.cc
@@ -0,0 +1,127 @@
+// 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/scheduler/base/task_queue_selector.h"
+
+#include "base/logging.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "components/scheduler/base/task_queue_impl.h"
+
+namespace scheduler {
+namespace internal {
+
+TaskQueueSelector::TaskQueueSelector()
+ : task_queue_sets_(TaskQueue::QUEUE_PRIORITY_COUNT),
+ starvation_count_(0),
+ task_queue_selector_observer_(nullptr) {}
+
+TaskQueueSelector::~TaskQueueSelector() {}
+
+void TaskQueueSelector::AddQueue(internal::TaskQueueImpl* queue) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ task_queue_sets_.AssignQueueToSet(queue, TaskQueue::NORMAL_PRIORITY);
+}
+
+void TaskQueueSelector::RemoveQueue(internal::TaskQueueImpl* queue) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ task_queue_sets_.RemoveQueue(queue);
+}
+
+void TaskQueueSelector::SetQueuePriority(internal::TaskQueueImpl* queue,
+ TaskQueue::QueuePriority priority) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ DCHECK_LT(priority, TaskQueue::QUEUE_PRIORITY_COUNT);
+ TaskQueue::QueuePriority old_priority =
+ static_cast<TaskQueue::QueuePriority>(queue->get_task_queue_set_index());
+ task_queue_sets_.AssignQueueToSet(queue, priority);
+ if (task_queue_selector_observer_ &&
+ old_priority == TaskQueue::DISABLED_PRIORITY) {
+ task_queue_selector_observer_->OnTaskQueueEnabled(queue);
+ }
+}
+
+bool TaskQueueSelector::IsQueueEnabled(
+ const internal::TaskQueueImpl* queue) const {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ return static_cast<TaskQueue::QueuePriority>(
+ queue->get_task_queue_set_index()) != TaskQueue::DISABLED_PRIORITY;
+}
+
+TaskQueue::QueuePriority TaskQueueSelector::NextPriority(
+ TaskQueue::QueuePriority priority) {
+ DCHECK(priority < TaskQueue::QUEUE_PRIORITY_COUNT);
+ return static_cast<TaskQueue::QueuePriority>(static_cast<int>(priority) + 1);
+}
+
+bool TaskQueueSelector::ChooseOldestWithPriority(
+ TaskQueue::QueuePriority priority,
+ internal::TaskQueueImpl** out_queue) const {
+ return task_queue_sets_.GetOldestQueueInSet(priority, out_queue);
+}
+
+bool TaskQueueSelector::SelectQueueToService(
+ internal::TaskQueueImpl** out_queue) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ // Always service the control queue if it has any work.
+ if (ChooseOldestWithPriority(TaskQueue::CONTROL_PRIORITY, out_queue)) {
+ DidSelectQueueWithPriority(TaskQueue::CONTROL_PRIORITY);
+ return true;
+ }
+ // Select from the normal priority queue if we are starving it.
+ if (starvation_count_ >= kMaxStarvationTasks &&
+ ChooseOldestWithPriority(TaskQueue::NORMAL_PRIORITY, out_queue)) {
+ DidSelectQueueWithPriority(TaskQueue::NORMAL_PRIORITY);
+ return true;
+ }
+ // Otherwise choose in priority order.
+ for (TaskQueue::QueuePriority priority = TaskQueue::HIGH_PRIORITY;
+ priority < TaskQueue::DISABLED_PRIORITY;
+ priority = NextPriority(priority)) {
+ if (ChooseOldestWithPriority(priority, out_queue)) {
+ DidSelectQueueWithPriority(priority);
+ return true;
+ }
+ }
+ return false;
+}
+
+void TaskQueueSelector::DidSelectQueueWithPriority(
+ TaskQueue::QueuePriority priority) {
+ switch (priority) {
+ case TaskQueue::CONTROL_PRIORITY:
+ break;
+ case TaskQueue::HIGH_PRIORITY:
+ starvation_count_++;
+ break;
+ case TaskQueue::NORMAL_PRIORITY:
+ case TaskQueue::BEST_EFFORT_PRIORITY:
+ starvation_count_ = 0;
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void TaskQueueSelector::AsValueInto(
+ base::trace_event::TracedValue* state) const {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ state->SetInteger("starvation_count", starvation_count_);
+}
+
+void TaskQueueSelector::SetTaskQueueSelectorObserver(Observer* observer) {
+ task_queue_selector_observer_ = observer;
+}
+
+bool TaskQueueSelector::EnabledWorkQueuesEmpty() const {
+ for (TaskQueue::QueuePriority priority = TaskQueue::HIGH_PRIORITY;
+ priority < TaskQueue::DISABLED_PRIORITY;
+ priority = NextPriority(priority)) {
+ if (!task_queue_sets_.IsSetEmpty(priority))
+ return false;
+ }
+ return true;
+}
+
+} // namespace internal
+} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_selector.h b/chromium/components/scheduler/base/task_queue_selector.h
new file mode 100644
index 00000000000..59e13493b55
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_selector.h
@@ -0,0 +1,100 @@
+// 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_SCHEDULER_BASE_TASK_QUEUE_SELECTOR_H_
+#define COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_SELECTOR_H_
+
+#include <set>
+
+#include "base/compiler_specific.h"
+#include "base/pending_task.h"
+#include "base/threading/thread_checker.h"
+#include "components/scheduler/base/task_queue_sets.h"
+#include "components/scheduler/scheduler_export.h"
+
+namespace scheduler {
+namespace internal {
+
+// TaskQueueSelector is used by the SchedulerHelper to enable prioritization
+// of particular task queues.
+class SCHEDULER_EXPORT TaskQueueSelector {
+ public:
+ TaskQueueSelector();
+ ~TaskQueueSelector();
+
+ // Set the priority of |queue| to |priority|.
+ void SetQueuePriority(internal::TaskQueueImpl* queue,
+ TaskQueue::QueuePriority priority);
+
+ // Whether |queue| is enabled.
+ bool IsQueueEnabled(const internal::TaskQueueImpl* queue) const;
+
+ // Called to register a queue that can be selected. This function is called
+ // on the main thread.
+ void AddQueue(internal::TaskQueueImpl* queue);
+
+ // The specified work will no longer be considered for selection. This
+ // function is called on the main thread.
+ void RemoveQueue(internal::TaskQueueImpl* queue);
+
+ // Called to choose the work queue from which the next task should be taken
+ // and run. Return true if |out_queue| indicates the queue to service or
+ // false to avoid running any task.
+ //
+ // This function is called on the main thread.
+ bool SelectQueueToService(internal::TaskQueueImpl** out_queue);
+
+ // Serialize the selector state for tracing.
+ void AsValueInto(base::trace_event::TracedValue* state) const;
+
+ class SCHEDULER_EXPORT Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Called when |queue| transitions from disabled to enabled.
+ virtual void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) = 0;
+ };
+
+ // Called once to set the Observer. This function is called
+ // on the main thread. If |observer| is null, then no callbacks will occur.
+ void SetTaskQueueSelectorObserver(Observer* observer);
+
+ TaskQueueSets* GetTaskQueueSets() { return &task_queue_sets_; }
+
+ // Returns true if all the enabled work queues are empty. Returns false
+ // otherwise.
+ bool EnabledWorkQueuesEmpty() const;
+
+ private:
+ // Returns the priority which is next after |priority|.
+ static TaskQueue::QueuePriority NextPriority(
+ TaskQueue::QueuePriority priority);
+
+ // Return true if |out_queue| contains the queue with the oldest pending task
+ // from the set of queues of |priority|, or false if all queues of that
+ // priority are empty.
+ bool ChooseOldestWithPriority(TaskQueue::QueuePriority priority,
+ internal::TaskQueueImpl** out_queue) const;
+
+ // Called whenever the selector chooses a task queue for execution with the
+ // priority |priority|.
+ void DidSelectQueueWithPriority(TaskQueue::QueuePriority priority);
+
+ // Number of high priority tasks which can be run before a normal priority
+ // task should be selected to prevent starvation.
+ // TODO(rmcilroy): Check if this is a good value.
+ static const size_t kMaxStarvationTasks = 5;
+
+ base::ThreadChecker main_thread_checker_;
+ TaskQueueSets task_queue_sets_;
+
+ size_t starvation_count_;
+ Observer* task_queue_selector_observer_; // NOT OWNED
+ DISALLOW_COPY_AND_ASSIGN(TaskQueueSelector);
+};
+
+} // namespace internal
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_SELECTOR_H
diff --git a/chromium/components/scheduler/base/task_queue_selector_unittest.cc b/chromium/components/scheduler/base/task_queue_selector_unittest.cc
new file mode 100644
index 00000000000..5f78459e5bc
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_selector_unittest.cc
@@ -0,0 +1,283 @@
+// 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/scheduler/base/task_queue_selector.h"
+
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/pending_task.h"
+#include "components/scheduler/base/task_queue_impl.h"
+#include "components/scheduler/base/task_queue_sets.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+
+namespace scheduler {
+namespace internal {
+
+class MockObserver : public TaskQueueSelector::Observer {
+ public:
+ MockObserver() {}
+ virtual ~MockObserver() {}
+
+ MOCK_METHOD1(OnTaskQueueEnabled, void(internal::TaskQueueImpl*));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockObserver);
+};
+
+class TaskQueueSelectorTest : public testing::Test {
+ public:
+ TaskQueueSelectorTest()
+ : test_closure_(base::Bind(&TaskQueueSelectorTest::TestFunction)) {}
+ ~TaskQueueSelectorTest() override {}
+
+ std::vector<TaskQueueImpl::Task> GetTasks(int count) {
+ std::vector<TaskQueueImpl::Task> tasks;
+ for (int i = 0; i < count; i++) {
+ TaskQueueImpl::Task task(FROM_HERE, test_closure_, 0, true);
+ task.set_enqueue_order(i);
+ tasks.push_back(task);
+ }
+ return tasks;
+ }
+
+ void PushTasks(const std::vector<TaskQueueImpl::Task>& tasks,
+ const size_t queue_indices[]) {
+ std::set<size_t> changed_queue_set;
+ for (size_t i = 0; i < tasks.size(); i++) {
+ changed_queue_set.insert(queue_indices[i]);
+ task_queues_[queue_indices[i]]->PushTaskOntoWorkQueueForTest(tasks[i]);
+ }
+ for (size_t queue_index : changed_queue_set) {
+ selector_.GetTaskQueueSets()->OnPushQueue(
+ task_queues_[queue_index].get());
+ }
+ }
+
+ std::vector<size_t> PopTasks() {
+ std::vector<size_t> order;
+ TaskQueueImpl* chosen_queue;
+ while (selector_.SelectQueueToService(&chosen_queue)) {
+ size_t chosen_queue_index =
+ queue_to_index_map_.find(chosen_queue)->second;
+ order.push_back(chosen_queue_index);
+ chosen_queue->PopTaskFromWorkQueueForTest();
+ selector_.GetTaskQueueSets()->OnPopQueue(chosen_queue);
+ }
+ return order;
+ }
+
+ static void TestFunction() {}
+
+ protected:
+ void SetUp() final {
+ for (size_t i = 0; i < kTaskQueueCount; i++) {
+ scoped_refptr<TaskQueueImpl> task_queue =
+ make_scoped_refptr(new TaskQueueImpl(
+ nullptr, TaskQueue::Spec("test queue"), "test", "test"));
+ selector_.AddQueue(task_queue.get());
+ task_queues_.push_back(task_queue);
+ }
+ for (size_t i = 0; i < kTaskQueueCount; i++) {
+ EXPECT_TRUE(selector_.IsQueueEnabled(task_queues_[i].get())) << i;
+ queue_to_index_map_.insert(std::make_pair(task_queues_[i].get(), i));
+ }
+ }
+
+ const size_t kTaskQueueCount = 5;
+ base::Closure test_closure_;
+ TaskQueueSelector selector_;
+ std::vector<scoped_refptr<TaskQueueImpl>> task_queues_;
+ std::map<TaskQueueImpl*, size_t> queue_to_index_map_;
+};
+
+TEST_F(TaskQueueSelectorTest, TestDefaultPriority) {
+ std::vector<TaskQueueImpl::Task> tasks = GetTasks(5);
+ size_t queue_order[] = {4, 3, 2, 1, 0};
+ PushTasks(tasks, queue_order);
+ EXPECT_THAT(PopTasks(), testing::ElementsAre(4, 3, 2, 1, 0));
+}
+
+TEST_F(TaskQueueSelectorTest, TestHighPriority) {
+ std::vector<TaskQueueImpl::Task> tasks = GetTasks(5);
+ size_t queue_order[] = {0, 1, 2, 3, 4};
+ PushTasks(tasks, queue_order);
+ selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
+ EXPECT_THAT(PopTasks(), testing::ElementsAre(2, 0, 1, 3, 4));
+}
+
+TEST_F(TaskQueueSelectorTest, TestBestEffortPriority) {
+ std::vector<TaskQueueImpl::Task> tasks = GetTasks(5);
+ size_t queue_order[] = {0, 1, 2, 3, 4};
+ PushTasks(tasks, queue_order);
+ selector_.SetQueuePriority(task_queues_[0].get(),
+ TaskQueue::BEST_EFFORT_PRIORITY);
+ selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
+ EXPECT_THAT(PopTasks(), testing::ElementsAre(2, 1, 3, 4, 0));
+}
+
+TEST_F(TaskQueueSelectorTest, TestControlPriority) {
+ std::vector<TaskQueueImpl::Task> tasks = GetTasks(5);
+ size_t queue_order[] = {0, 1, 2, 3, 4};
+ PushTasks(tasks, queue_order);
+ selector_.SetQueuePriority(task_queues_[4].get(),
+ TaskQueue::CONTROL_PRIORITY);
+ EXPECT_TRUE(selector_.IsQueueEnabled(task_queues_[4].get()));
+ selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
+ EXPECT_TRUE(selector_.IsQueueEnabled(task_queues_[2].get()));
+ EXPECT_THAT(PopTasks(), testing::ElementsAre(4, 2, 0, 1, 3));
+}
+
+TEST_F(TaskQueueSelectorTest, TestObserverWithSetQueuePriority) {
+ selector_.SetQueuePriority(task_queues_[1].get(),
+ TaskQueue::DISABLED_PRIORITY);
+ MockObserver mock_observer;
+ selector_.SetTaskQueueSelectorObserver(&mock_observer);
+ EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1);
+ selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY);
+}
+
+TEST_F(TaskQueueSelectorTest,
+ TestObserverWithSetQueuePriorityAndQueueAlreadyEnabed) {
+ selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY);
+ MockObserver mock_observer;
+ selector_.SetTaskQueueSelectorObserver(&mock_observer);
+ EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(0);
+ selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY);
+}
+
+TEST_F(TaskQueueSelectorTest, TestDisableEnable) {
+ MockObserver mock_observer;
+ selector_.SetTaskQueueSelectorObserver(&mock_observer);
+
+ std::vector<TaskQueueImpl::Task> tasks = GetTasks(5);
+ size_t queue_order[] = {0, 1, 2, 3, 4};
+ PushTasks(tasks, queue_order);
+ selector_.SetQueuePriority(task_queues_[2].get(),
+ TaskQueue::DISABLED_PRIORITY);
+ EXPECT_FALSE(selector_.IsQueueEnabled(task_queues_[2].get()));
+ selector_.SetQueuePriority(task_queues_[4].get(),
+ TaskQueue::DISABLED_PRIORITY);
+ EXPECT_FALSE(selector_.IsQueueEnabled(task_queues_[4].get()));
+ EXPECT_THAT(PopTasks(), testing::ElementsAre(0, 1, 3));
+
+ EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(2);
+ selector_.SetQueuePriority(task_queues_[2].get(),
+ TaskQueue::BEST_EFFORT_PRIORITY);
+ EXPECT_THAT(PopTasks(), testing::ElementsAre(2));
+ selector_.SetQueuePriority(task_queues_[4].get(), TaskQueue::NORMAL_PRIORITY);
+ EXPECT_THAT(PopTasks(), testing::ElementsAre(4));
+}
+
+TEST_F(TaskQueueSelectorTest, TestEmptyQueues) {
+ TaskQueueImpl* chosen_queue = nullptr;
+ EXPECT_FALSE(selector_.SelectQueueToService(&chosen_queue));
+
+ // Test only disabled queues.
+ std::vector<TaskQueueImpl::Task> tasks = GetTasks(1);
+ size_t queue_order[] = {0};
+ PushTasks(tasks, queue_order);
+ selector_.SetQueuePriority(task_queues_[0].get(),
+ TaskQueue::DISABLED_PRIORITY);
+ EXPECT_FALSE(selector_.IsQueueEnabled(task_queues_[0].get()));
+ EXPECT_FALSE(selector_.SelectQueueToService(&chosen_queue));
+}
+
+TEST_F(TaskQueueSelectorTest, TestAge) {
+ std::vector<TaskQueueImpl::Task> tasks;
+ int enqueue_order[] = {10, 1, 2, 9, 4};
+ for (int i = 0; i < 5; i++) {
+ TaskQueueImpl::Task task(FROM_HERE, test_closure_, 0, true);
+ task.set_enqueue_order(enqueue_order[i]);
+ tasks.push_back(task);
+ }
+ size_t queue_order[] = {0, 1, 2, 3, 4};
+ PushTasks(tasks, queue_order);
+ EXPECT_THAT(PopTasks(), testing::ElementsAre(1, 2, 4, 3, 0));
+}
+
+TEST_F(TaskQueueSelectorTest, TestControlStarvesOthers) {
+ std::vector<TaskQueueImpl::Task> tasks = GetTasks(4);
+ size_t queue_order[] = {0, 1, 2, 3};
+ PushTasks(tasks, queue_order);
+ selector_.SetQueuePriority(task_queues_[3].get(),
+ TaskQueue::CONTROL_PRIORITY);
+ selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
+ selector_.SetQueuePriority(task_queues_[1].get(),
+ TaskQueue::BEST_EFFORT_PRIORITY);
+ for (int i = 0; i < 100; i++) {
+ TaskQueueImpl* chosen_queue = nullptr;
+ EXPECT_TRUE(selector_.SelectQueueToService(&chosen_queue));
+ EXPECT_EQ(task_queues_[3].get(), chosen_queue);
+ // Don't remove task from queue to simulate all queues still being full.
+ }
+}
+
+TEST_F(TaskQueueSelectorTest, TestHighPriorityDoesNotStarveNormal) {
+ std::vector<TaskQueueImpl::Task> tasks = GetTasks(3);
+ size_t queue_order[] = {0, 1, 2};
+ PushTasks(tasks, queue_order);
+ selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::HIGH_PRIORITY);
+ selector_.SetQueuePriority(task_queues_[1].get(),
+ TaskQueue::BEST_EFFORT_PRIORITY);
+ size_t counts[] = {0, 0, 0};
+ for (int i = 0; i < 100; i++) {
+ TaskQueueImpl* chosen_queue = nullptr;
+ EXPECT_TRUE(selector_.SelectQueueToService(&chosen_queue));
+ size_t chosen_queue_index = queue_to_index_map_.find(chosen_queue)->second;
+ counts[chosen_queue_index]++;
+ // Don't remove task from queue to simulate all queues still being full.
+ }
+ EXPECT_GT(counts[0], 0ul); // Check high doesn't starve normal.
+ EXPECT_GT(counts[2], counts[0]); // Check high gets more chance to run.
+ EXPECT_EQ(0ul, counts[1]); // Check best effort is starved.
+}
+
+TEST_F(TaskQueueSelectorTest, TestBestEffortGetsStarved) {
+ std::vector<TaskQueueImpl::Task> tasks = GetTasks(2);
+ size_t queue_order[] = {0, 1};
+ PushTasks(tasks, queue_order);
+ selector_.SetQueuePriority(task_queues_[0].get(),
+ TaskQueue::BEST_EFFORT_PRIORITY);
+ selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY);
+ TaskQueueImpl* chosen_queue = nullptr;
+ for (int i = 0; i < 100; i++) {
+ EXPECT_TRUE(selector_.SelectQueueToService(&chosen_queue));
+ EXPECT_EQ(task_queues_[1].get(), chosen_queue);
+ // Don't remove task from queue to simulate all queues still being full.
+ }
+ selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::HIGH_PRIORITY);
+ for (int i = 0; i < 100; i++) {
+ EXPECT_TRUE(selector_.SelectQueueToService(&chosen_queue));
+ EXPECT_EQ(task_queues_[1].get(), chosen_queue);
+ // Don't remove task from queue to simulate all queues still being full.
+ }
+ selector_.SetQueuePriority(task_queues_[1].get(),
+ TaskQueue::CONTROL_PRIORITY);
+ for (int i = 0; i < 100; i++) {
+ EXPECT_TRUE(selector_.SelectQueueToService(&chosen_queue));
+ EXPECT_EQ(task_queues_[1].get(), chosen_queue);
+ // Don't remove task from queue to simulate all queues still being full.
+ }
+}
+
+TEST_F(TaskQueueSelectorTest, DisabledPriorityIsPenultimate) {
+ EXPECT_EQ(TaskQueue::QUEUE_PRIORITY_COUNT, TaskQueue::DISABLED_PRIORITY + 1);
+}
+
+TEST_F(TaskQueueSelectorTest, EnabledWorkQueuesEmpty) {
+ EXPECT_TRUE(selector_.EnabledWorkQueuesEmpty());
+ std::vector<TaskQueueImpl::Task> tasks = GetTasks(2);
+ size_t queue_order[] = {0, 1};
+ PushTasks(tasks, queue_order);
+
+ EXPECT_FALSE(selector_.EnabledWorkQueuesEmpty());
+ PopTasks();
+ EXPECT_TRUE(selector_.EnabledWorkQueuesEmpty());
+}
+
+} // namespace internal
+} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_sets.cc b/chromium/components/scheduler/base/task_queue_sets.cc
new file mode 100644
index 00000000000..9463823fb81
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_sets.cc
@@ -0,0 +1,96 @@
+// 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/scheduler/base/task_queue_sets.h"
+
+#include "base/logging.h"
+#include "components/scheduler/base/task_queue_impl.h"
+
+namespace scheduler {
+namespace internal {
+
+TaskQueueSets::TaskQueueSets(size_t num_sets)
+ : enqueue_order_to_queue_maps_(num_sets) {}
+
+TaskQueueSets::~TaskQueueSets() {}
+
+void TaskQueueSets::RemoveQueue(internal::TaskQueueImpl* queue) {
+ int enqueue_order;
+ bool has_enqueue_order =
+ queue->GetWorkQueueFrontTaskEnqueueOrder(&enqueue_order);
+ if (!has_enqueue_order)
+ return;
+ size_t set_index = queue->get_task_queue_set_index();
+ DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size());
+ DCHECK_EQ(
+ queue,
+ enqueue_order_to_queue_maps_[set_index].find(enqueue_order)->second);
+ enqueue_order_to_queue_maps_[set_index].erase(enqueue_order);
+}
+
+void TaskQueueSets::AssignQueueToSet(internal::TaskQueueImpl* queue,
+ size_t set_index) {
+ DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size());
+ int enqueue_order;
+ bool has_enqueue_order =
+ queue->GetWorkQueueFrontTaskEnqueueOrder(&enqueue_order);
+ size_t old_set = queue->get_task_queue_set_index();
+ DCHECK_LT(old_set, enqueue_order_to_queue_maps_.size());
+ queue->set_task_queue_set_index(set_index);
+ if (!has_enqueue_order)
+ return;
+ enqueue_order_to_queue_maps_[old_set].erase(enqueue_order);
+ enqueue_order_to_queue_maps_[set_index].insert(
+ std::make_pair(enqueue_order, queue));
+}
+
+void TaskQueueSets::OnPushQueue(internal::TaskQueueImpl* queue) {
+ int enqueue_order;
+ bool has_enqueue_order =
+ queue->GetWorkQueueFrontTaskEnqueueOrder(&enqueue_order);
+ DCHECK(has_enqueue_order);
+ size_t set_index = queue->get_task_queue_set_index();
+ DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size()) << " set_index = "
+ << set_index;
+ enqueue_order_to_queue_maps_[set_index].insert(
+ std::make_pair(enqueue_order, queue));
+}
+
+void TaskQueueSets::OnPopQueue(internal::TaskQueueImpl* queue) {
+ size_t set_index = queue->get_task_queue_set_index();
+ DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size());
+ DCHECK(!enqueue_order_to_queue_maps_[set_index].empty()) << " set_index = "
+ << set_index;
+ DCHECK_EQ(enqueue_order_to_queue_maps_[set_index].begin()->second, queue)
+ << " set_index = " << set_index;
+ // O(1) amortised.
+ enqueue_order_to_queue_maps_[set_index].erase(
+ enqueue_order_to_queue_maps_[set_index].begin());
+ int enqueue_order;
+ bool has_enqueue_order =
+ queue->GetWorkQueueFrontTaskEnqueueOrder(&enqueue_order);
+ if (!has_enqueue_order)
+ return;
+ enqueue_order_to_queue_maps_[set_index].insert(
+ std::make_pair(enqueue_order, queue));
+}
+
+bool TaskQueueSets::GetOldestQueueInSet(
+ size_t set_index,
+ internal::TaskQueueImpl** out_queue) const {
+ DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size());
+ if (enqueue_order_to_queue_maps_[set_index].empty())
+ return false;
+ *out_queue = enqueue_order_to_queue_maps_[set_index].begin()->second;
+ return true;
+}
+
+bool TaskQueueSets::IsSetEmpty(size_t set_index) const {
+ DCHECK_LT(set_index, enqueue_order_to_queue_maps_.size()) << " set_index = "
+ << set_index;
+ return enqueue_order_to_queue_maps_[set_index].empty();
+}
+
+} // namespace internal
+} // namespace scheduler
diff --git a/chromium/components/scheduler/base/task_queue_sets.h b/chromium/components/scheduler/base/task_queue_sets.h
new file mode 100644
index 00000000000..e3b17ec421e
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_sets.h
@@ -0,0 +1,75 @@
+// 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_SCHEDULER_BASE_TASK_QUEUE_SETS_H_
+#define COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_SETS_H_
+
+#include <map>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "components/scheduler/base/task_queue.h"
+#include "components/scheduler/scheduler_export.h"
+
+namespace scheduler {
+namespace internal {
+class TaskQueueImpl;
+
+class SCHEDULER_EXPORT TaskQueueSets {
+ public:
+ explicit TaskQueueSets(size_t num_sets);
+ ~TaskQueueSets();
+
+ // O(log num queues)
+ void RemoveQueue(internal::TaskQueueImpl* queue);
+
+ // O(log num queues)
+ void AssignQueueToSet(internal::TaskQueueImpl* queue, size_t set_index);
+
+ // O(log num queues)
+ void OnPushQueue(internal::TaskQueueImpl* queue);
+
+ // If empty it's O(1) amortized, otherwise it's O(log num queues)
+ void OnPopQueue(internal::TaskQueueImpl* queue);
+
+ // O(1)
+ bool GetOldestQueueInSet(size_t set_index,
+ internal::TaskQueueImpl** out_queue) const;
+
+ // O(1)
+ bool IsSetEmpty(size_t set_index) const;
+
+ private:
+ struct EnqueueOrderComparitor {
+ // The enqueueorder numbers are generated in sequence. These will
+ // eventually overflow and roll-over to negative numbers. We must take care
+ // to preserve the ordering of the map when this happens.
+ // NOTE we assume that tasks don't get starved for extended periods so that
+ // the task queue ages in a set have at most one roll-over.
+ // NOTE signed integer overflow behavior is undefined in C++ so we can't
+ // use the (a - b) < 0 trick here, because the optimizer won't necessarily
+ // do what we expect.
+ // TODO(alexclarke): Consider making age and sequence_num unsigned, because
+ // unsigned integer overflow behavior is defined.
+ bool operator()(int a, int b) const {
+ if (a < 0 && b >= 0)
+ return false;
+ if (b < 0 && a >= 0)
+ return true;
+ return a < b;
+ }
+ };
+
+ typedef std::map<int, internal::TaskQueueImpl*, EnqueueOrderComparitor>
+ EnqueueOrderToQueueMap;
+ std::vector<EnqueueOrderToQueueMap> enqueue_order_to_queue_maps_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskQueueSets);
+};
+
+} // namespace internal
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_BASE_TASK_QUEUE_SETS_H_
diff --git a/chromium/components/scheduler/base/task_queue_sets_unittest.cc b/chromium/components/scheduler/base/task_queue_sets_unittest.cc
new file mode 100644
index 00000000000..2daf205c5a3
--- /dev/null
+++ b/chromium/components/scheduler/base/task_queue_sets_unittest.cc
@@ -0,0 +1,239 @@
+// 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/scheduler/base/task_queue_sets.h"
+
+#include "components/scheduler/base/task_queue_impl.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace scheduler {
+namespace internal {
+
+class TaskQueueSetsTest : public testing::Test {
+ public:
+ void SetUp() override { task_queue_sets_.reset(new TaskQueueSets(kNumSets)); }
+
+ protected:
+ enum {
+ kNumSets = 5 // An arbitary choice.
+ };
+
+ TaskQueueImpl* NewTaskQueue(const char* queue_name) {
+ scoped_refptr<internal::TaskQueueImpl> queue =
+ make_scoped_refptr(new internal::TaskQueueImpl(
+ nullptr, TaskQueue::Spec(queue_name), "test", "test"));
+ task_queues_.push_back(queue);
+ return queue.get();
+ }
+
+ TaskQueueImpl::Task FakeTaskWithEnqueueOrder(int enqueue_order) {
+ TaskQueueImpl::Task fake_task(FROM_HERE, base::Closure(), 0, true);
+ fake_task.set_enqueue_order(enqueue_order);
+ return fake_task;
+ }
+
+ std::vector<scoped_refptr<internal::TaskQueueImpl>> task_queues_;
+ scoped_ptr<TaskQueueSets> task_queue_sets_;
+};
+
+TEST_F(TaskQueueSetsTest, AssignQueueToSet) {
+ internal::TaskQueueImpl* queue = NewTaskQueue("queue");
+ size_t set = TaskQueue::NORMAL_PRIORITY;
+ task_queue_sets_->AssignQueueToSet(queue, set);
+
+ EXPECT_EQ(set, queue->get_task_queue_set_index());
+}
+
+TEST_F(TaskQueueSetsTest, GetOldestQueueInSet_QueueEmpty) {
+ internal::TaskQueueImpl* queue = NewTaskQueue("queue");
+ size_t set = TaskQueue::NORMAL_PRIORITY;
+ task_queue_sets_->AssignQueueToSet(queue, set);
+
+ internal::TaskQueueImpl* selected_queue;
+ EXPECT_FALSE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+}
+
+TEST_F(TaskQueueSetsTest, OnPushQueue) {
+ internal::TaskQueueImpl* queue = NewTaskQueue("queue");
+ size_t set = TaskQueue::NORMAL_PRIORITY;
+ task_queue_sets_->AssignQueueToSet(queue, set);
+
+ internal::TaskQueueImpl* selected_queue;
+ EXPECT_FALSE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+
+ queue->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(10));
+ task_queue_sets_->OnPushQueue(queue);
+
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+ EXPECT_EQ(queue, selected_queue);
+}
+
+TEST_F(TaskQueueSetsTest, GetOldestQueueInSet_SingleTaskInSet) {
+ internal::TaskQueueImpl* queue = NewTaskQueue("queue");
+ queue->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(10));
+ size_t set = 1;
+ task_queue_sets_->AssignQueueToSet(queue, set);
+
+ internal::TaskQueueImpl* selected_queue;
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+ EXPECT_EQ(queue, selected_queue);
+}
+
+TEST_F(TaskQueueSetsTest, GetOldestQueueInSet_MultipleAgesInSet) {
+ internal::TaskQueueImpl* queue1 = NewTaskQueue("queue1");
+ internal::TaskQueueImpl* queue2 = NewTaskQueue("queue2");
+ internal::TaskQueueImpl* queue3 = NewTaskQueue("queue2");
+ queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(6));
+ queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(5));
+ queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(4));
+ size_t set = 2;
+ task_queue_sets_->AssignQueueToSet(queue1, set);
+ task_queue_sets_->AssignQueueToSet(queue2, set);
+ task_queue_sets_->AssignQueueToSet(queue3, set);
+
+ internal::TaskQueueImpl* selected_queue;
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+ EXPECT_EQ(queue3, selected_queue);
+}
+
+TEST_F(TaskQueueSetsTest, OnPopQueue) {
+ internal::TaskQueueImpl* queue1 = NewTaskQueue("queue1");
+ internal::TaskQueueImpl* queue2 = NewTaskQueue("queue2");
+ internal::TaskQueueImpl* queue3 = NewTaskQueue("queue3");
+ queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(6));
+ queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(3));
+ queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(1));
+ queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(4));
+ size_t set = 3;
+ task_queue_sets_->AssignQueueToSet(queue1, set);
+ task_queue_sets_->AssignQueueToSet(queue2, set);
+ task_queue_sets_->AssignQueueToSet(queue3, set);
+
+ internal::TaskQueueImpl* selected_queue;
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+ EXPECT_EQ(queue2, selected_queue);
+
+ queue2->PopTaskFromWorkQueueForTest();
+ task_queue_sets_->OnPopQueue(queue2);
+
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+ EXPECT_EQ(queue2, selected_queue);
+}
+
+TEST_F(TaskQueueSetsTest, OnPopQueue_QueueBecomesEmpty) {
+ internal::TaskQueueImpl* queue1 = NewTaskQueue("queue");
+ internal::TaskQueueImpl* queue2 = NewTaskQueue("queue");
+ internal::TaskQueueImpl* queue3 = NewTaskQueue("queue");
+ queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(6));
+ queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(5));
+ queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(4));
+ size_t set = 4;
+ task_queue_sets_->AssignQueueToSet(queue1, set);
+ task_queue_sets_->AssignQueueToSet(queue2, set);
+ task_queue_sets_->AssignQueueToSet(queue3, set);
+
+ internal::TaskQueueImpl* selected_queue;
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+ EXPECT_EQ(queue3, selected_queue);
+
+ queue3->PopTaskFromWorkQueueForTest();
+ task_queue_sets_->OnPopQueue(queue3);
+
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+ EXPECT_EQ(queue2, selected_queue);
+}
+
+TEST_F(TaskQueueSetsTest,
+ GetOldestQueueInSet_MultipleAgesInSetIntegerRollover) {
+ internal::TaskQueueImpl* queue1 = NewTaskQueue("queue1");
+ internal::TaskQueueImpl* queue2 = NewTaskQueue("queue2");
+ internal::TaskQueueImpl* queue3 = NewTaskQueue("queue3");
+ queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(0x7ffffff1));
+ queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(0x7ffffff0));
+ queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(-0x7ffffff1));
+ size_t set = 0;
+ task_queue_sets_->AssignQueueToSet(queue1, set);
+ task_queue_sets_->AssignQueueToSet(queue2, set);
+ task_queue_sets_->AssignQueueToSet(queue3, set);
+
+ internal::TaskQueueImpl* selected_queue;
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+ EXPECT_EQ(queue2, selected_queue);
+}
+
+TEST_F(TaskQueueSetsTest, GetOldestQueueInSet_MultipleAgesInSet_RemoveQueue) {
+ internal::TaskQueueImpl* queue1 = NewTaskQueue("queue1");
+ internal::TaskQueueImpl* queue2 = NewTaskQueue("queue2");
+ internal::TaskQueueImpl* queue3 = NewTaskQueue("queue3");
+ queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(6));
+ queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(5));
+ queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(4));
+ size_t set = 1;
+ task_queue_sets_->AssignQueueToSet(queue1, set);
+ task_queue_sets_->AssignQueueToSet(queue2, set);
+ task_queue_sets_->AssignQueueToSet(queue3, set);
+ task_queue_sets_->RemoveQueue(queue3);
+
+ internal::TaskQueueImpl* selected_queue;
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set, &selected_queue));
+ EXPECT_EQ(queue2, selected_queue);
+}
+
+TEST_F(TaskQueueSetsTest, AssignQueueToSet_Complex) {
+ internal::TaskQueueImpl* queue1 = NewTaskQueue("queue1");
+ internal::TaskQueueImpl* queue2 = NewTaskQueue("queue2");
+ internal::TaskQueueImpl* queue3 = NewTaskQueue("queue3");
+ internal::TaskQueueImpl* queue4 = NewTaskQueue("queue4");
+ queue1->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(6));
+ queue2->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(5));
+ queue3->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(4));
+ queue4->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(3));
+ size_t set1 = 1;
+ size_t set2 = 2;
+ task_queue_sets_->AssignQueueToSet(queue1, set1);
+ task_queue_sets_->AssignQueueToSet(queue2, set1);
+ task_queue_sets_->AssignQueueToSet(queue3, set2);
+ task_queue_sets_->AssignQueueToSet(queue4, set2);
+
+ internal::TaskQueueImpl* selected_queue;
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set1, &selected_queue));
+ EXPECT_EQ(queue2, selected_queue);
+
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set2, &selected_queue));
+ EXPECT_EQ(queue4, selected_queue);
+
+ task_queue_sets_->AssignQueueToSet(queue4, set1);
+
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set1, &selected_queue));
+ EXPECT_EQ(queue4, selected_queue);
+
+ EXPECT_TRUE(task_queue_sets_->GetOldestQueueInSet(set2, &selected_queue));
+ EXPECT_EQ(queue3, selected_queue);
+}
+
+TEST_F(TaskQueueSetsTest, IsSetEmpty_NoWork) {
+ size_t set = 0;
+ EXPECT_TRUE(task_queue_sets_->IsSetEmpty(set));
+
+ internal::TaskQueueImpl* queue = NewTaskQueue("queue");
+ task_queue_sets_->AssignQueueToSet(queue, set);
+ EXPECT_TRUE(task_queue_sets_->IsSetEmpty(set));
+}
+
+TEST_F(TaskQueueSetsTest, IsSetEmpty_Work) {
+ size_t set = 0;
+ EXPECT_TRUE(task_queue_sets_->IsSetEmpty(set));
+
+ internal::TaskQueueImpl* queue = NewTaskQueue("queue");
+ queue->PushTaskOntoWorkQueueForTest(FakeTaskWithEnqueueOrder(1));
+ task_queue_sets_->AssignQueueToSet(queue, set);
+ EXPECT_FALSE(task_queue_sets_->IsSetEmpty(set));
+
+ queue->PopTaskFromWorkQueueForTest();
+ task_queue_sets_->OnPopQueue(queue);
+ EXPECT_TRUE(task_queue_sets_->IsSetEmpty(set));
+}
+
+} // namespace internal
+} // namespace scheduler
diff --git a/chromium/components/scheduler/base/test_always_fail_time_source.cc b/chromium/components/scheduler/base/test_always_fail_time_source.cc
new file mode 100644
index 00000000000..254298453f9
--- /dev/null
+++ b/chromium/components/scheduler/base/test_always_fail_time_source.cc
@@ -0,0 +1,21 @@
+// 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/scheduler/base/test_always_fail_time_source.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace scheduler {
+
+TestAlwaysFailTimeSource::TestAlwaysFailTimeSource() {
+}
+
+TestAlwaysFailTimeSource::~TestAlwaysFailTimeSource() {
+}
+
+base::TimeTicks TestAlwaysFailTimeSource::NowTicks() {
+ ADD_FAILURE() << "NowTicks() was called!";
+ return base::TimeTicks();
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/base/test_always_fail_time_source.h b/chromium/components/scheduler/base/test_always_fail_time_source.h
new file mode 100644
index 00000000000..9a48d932550
--- /dev/null
+++ b/chromium/components/scheduler/base/test_always_fail_time_source.h
@@ -0,0 +1,25 @@
+// 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_SCHEDULER_BASE_TEST_ALWAYS_FAIL_TIME_SOURCE_H_
+#define COMPONENTS_SCHEDULER_BASE_TEST_ALWAYS_FAIL_TIME_SOURCE_H_
+
+#include "base/time/tick_clock.h"
+
+namespace scheduler {
+
+class TestAlwaysFailTimeSource : public base::TickClock {
+ public:
+ explicit TestAlwaysFailTimeSource();
+ ~TestAlwaysFailTimeSource() override;
+
+ base::TimeTicks NowTicks() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestAlwaysFailTimeSource);
+};
+
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_BASE_TEST_ALWAYS_FAIL_TIME_SOURCE_H_
diff --git a/chromium/components/scheduler/child/test_time_source.cc b/chromium/components/scheduler/base/test_time_source.cc
index d01c5edf811..7c620ad6789 100644
--- a/chromium/components/scheduler/child/test_time_source.cc
+++ b/chromium/components/scheduler/base/test_time_source.cc
@@ -2,16 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/scheduler/child/test_time_source.h"
+#include "components/scheduler/base/test_time_source.h"
namespace scheduler {
TestTimeSource::TestTimeSource(base::SimpleTestTickClock* time_source)
- : time_source_(time_source) {
-}
+ : time_source_(time_source) {}
-TestTimeSource::~TestTimeSource() {
-}
+TestTimeSource::~TestTimeSource() {}
base::TimeTicks TestTimeSource::NowTicks() {
return time_source_->NowTicks();
diff --git a/chromium/components/scheduler/child/test_time_source.h b/chromium/components/scheduler/base/test_time_source.h
index d8bd1742e01..a09e939ed3f 100644
--- a/chromium/components/scheduler/child/test_time_source.h
+++ b/chromium/components/scheduler/base/test_time_source.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_SCHEDULER_CHILD_TEST_TIME_SOURCE_H_
-#define COMPONENTS_SCHEDULER_CHILD_TEST_TIME_SOURCE_H_
+#ifndef COMPONENTS_SCHEDULER_BASE_TEST_TIME_SOURCE_H_
+#define COMPONENTS_SCHEDULER_BASE_TEST_TIME_SOURCE_H_
#include "base/memory/ref_counted.h"
#include "base/test/simple_test_tick_clock.h"
@@ -27,4 +27,4 @@ class TestTimeSource : public base::TickClock {
} // namespace scheduler
-#endif // COMPONENTS_SCHEDULER_CHILD_TEST_TIME_SOURCE_H_
+#endif // COMPONENTS_SCHEDULER_BASE_TEST_TIME_SOURCE_H_
diff --git a/chromium/components/scheduler/child/DEPS b/chromium/components/scheduler/child/DEPS
index d385f3506b8..87faf7366db 100644
--- a/chromium/components/scheduler/child/DEPS
+++ b/chromium/components/scheduler/child/DEPS
@@ -1,5 +1,5 @@
include_rules = [
- "+components/scheduler/common",
+ "+components/scheduler/base",
"+components/scheduler/scheduler_export.h",
"+third_party/WebKit/public/platform",
]
diff --git a/chromium/components/scheduler/child/child_scheduler.h b/chromium/components/scheduler/child/child_scheduler.h
index 14f9efb1caa..b74be4ec47e 100644
--- a/chromium/components/scheduler/child/child_scheduler.h
+++ b/chromium/components/scheduler/child/child_scheduler.h
@@ -6,8 +6,8 @@
#define COMPONENTS_SCHEDULER_CHILD_CHILD_SCHEDULER_H_
#include "base/message_loop/message_loop.h"
+#include "components/scheduler/base/task_queue.h"
#include "components/scheduler/child/single_thread_idle_task_runner.h"
-#include "components/scheduler/child/task_queue.h"
#include "components/scheduler/scheduler_export.h"
namespace base {
@@ -21,6 +21,7 @@ class SCHEDULER_EXPORT ChildScheduler {
virtual ~ChildScheduler() {}
// Returns the default task runner.
+ // TODO(alexclarke): Change this to return a SingleThreadIdleTaskRunner.
virtual scoped_refptr<TaskQueue> DefaultTaskRunner() = 0;
// Returns the idle task runner. Tasks posted to this runner may be reordered
diff --git a/chromium/components/scheduler/child/idle_helper.cc b/chromium/components/scheduler/child/idle_helper.cc
index e3adeb0c483..dc58c88fd7f 100644
--- a/chromium/components/scheduler/child/idle_helper.cc
+++ b/chromium/components/scheduler/child/idle_helper.cc
@@ -7,30 +7,29 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
+#include "components/scheduler/base/task_queue.h"
+#include "components/scheduler/base/task_queue_manager.h"
#include "components/scheduler/child/scheduler_helper.h"
-#include "components/scheduler/child/task_queue.h"
namespace scheduler {
IdleHelper::IdleHelper(
SchedulerHelper* helper,
Delegate* delegate,
- size_t idle_queue_index,
const char* tracing_category,
const char* disabled_by_default_tracing_category,
const char* idle_period_tracing_name,
base::TimeDelta required_quiescence_duration_before_long_idle_period)
: helper_(helper),
delegate_(delegate),
- idle_queue_index_(idle_queue_index),
+ idle_queue_(
+ helper_->NewTaskQueue(TaskQueue::Spec("idle_tq").SetPumpPolicy(
+ TaskQueue::PumpPolicy::MANUAL))),
state_(helper,
delegate,
tracing_category,
disabled_by_default_tracing_category,
idle_period_tracing_name),
- quiescence_monitored_task_queue_mask_(
- helper_->GetQuiescenceMonitoredTaskQueueMask() &
- ~(1ull << idle_queue_index_)),
required_quiescence_duration_before_long_idle_period_(
required_quiescence_duration_before_long_idle_period),
disabled_by_default_tracing_category_(
@@ -43,12 +42,10 @@ IdleHelper::IdleHelper(
&IdleHelper::OnIdleTaskPostedOnMainThread, weak_idle_helper_ptr_));
idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner(
- helper_->TaskRunnerForQueue(idle_queue_index_),
- helper_->ControlAfterWakeUpTaskRunner(), this, tracing_category));
+ idle_queue_, helper_->ControlAfterWakeUpTaskRunner(), this,
+ tracing_category));
- helper_->DisableQueue(idle_queue_index_);
- helper_->SetPumpPolicy(idle_queue_index_,
- TaskQueueManager::PumpPolicy::MANUAL);
+ idle_queue_->SetQueuePriority(TaskQueue::DISABLED_PRIORITY);
helper_->AddTaskObserver(this);
}
@@ -94,7 +91,7 @@ IdleHelper::IdlePeriodState IdleHelper::ComputeNewLongIdlePeriodState(
if (long_idle_period_duration >=
base::TimeDelta::FromMilliseconds(kMinimumIdlePeriodDurationMillis)) {
*next_long_idle_period_delay_out = long_idle_period_duration;
- if (helper_->IsQueueEmpty(idle_queue_index_)) {
+ if (idle_queue_->IsQueueEmpty()) {
return IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED;
} else if (long_idle_period_duration == max_long_idle_period_duration) {
return IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE;
@@ -119,17 +116,10 @@ bool IdleHelper::ShouldWaitForQuiescence() {
base::TimeDelta())
return false;
- uint64 task_queues_run_since_last_check_bitmap =
- helper_->GetAndClearTaskWasRunOnQueueBitmap() &
- quiescence_monitored_task_queue_mask_;
-
+ bool system_is_quiescent = helper_->GetAndClearSystemIsQuiescentBit();
TRACE_EVENT1(disabled_by_default_tracing_category_, "ShouldWaitForQuiescence",
- "task_queues_run_since_last_check_bitmap",
- task_queues_run_since_last_check_bitmap);
-
- // If anything was run on the queues we care about, then we're not quiescent
- // and we should wait.
- return task_queues_run_since_last_check_bitmap != 0;
+ "system_is_quiescent", system_is_quiescent);
+ return !system_is_quiescent;
}
void IdleHelper::EnableLongIdlePeriod() {
@@ -182,9 +172,8 @@ void IdleHelper::StartIdlePeriod(IdlePeriodState new_state,
}
TRACE_EVENT0(disabled_by_default_tracing_category_, "StartIdlePeriod");
- helper_->EnableQueue(idle_queue_index_,
- PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
- helper_->PumpQueue(idle_queue_index_);
+ idle_queue_->SetQueuePriority(TaskQueue::BEST_EFFORT_PRIORITY);
+ idle_queue_->PumpQueue();
state_.UpdateState(new_state, idle_period_deadline, now);
}
@@ -200,7 +189,7 @@ void IdleHelper::EndIdlePeriod() {
if (!IsInIdlePeriod(state_.idle_period_state()))
return;
- helper_->DisableQueue(idle_queue_index_);
+ idle_queue_->SetQueuePriority(TaskQueue::DISABLED_PRIORITY);
state_.UpdateState(IdlePeriodState::NOT_IN_IDLE_PERIOD, base::TimeTicks(),
base::TimeTicks());
}
@@ -232,14 +221,13 @@ void IdleHelper::UpdateLongIdlePeriodStateAfterIdleTask() {
DCHECK(IsInLongIdlePeriod(state_.idle_period_state()));
TRACE_EVENT0(disabled_by_default_tracing_category_,
"UpdateLongIdlePeriodStateAfterIdleTask");
- TaskQueueManager::QueueState queue_state =
- helper_->GetQueueState(idle_queue_index_);
- if (queue_state == TaskQueueManager::QueueState::EMPTY) {
+ TaskQueue::QueueState queue_state = idle_queue_->GetQueueState();
+ if (queue_state == TaskQueue::QueueState::EMPTY) {
// If there are no more idle tasks then pause long idle period ticks until a
// new idle task is posted.
state_.UpdateState(IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED,
state_.idle_period_deadline(), base::TimeTicks());
- } else if (queue_state == TaskQueueManager::QueueState::NEEDS_PUMPING) {
+ } else if (queue_state == TaskQueue::QueueState::NEEDS_PUMPING) {
// If there is still idle work to do then just start the next idle period.
base::TimeDelta next_long_idle_period_delay;
if (state_.idle_period_state() ==
@@ -291,8 +279,6 @@ void IdleHelper::OnIdleTaskPostedOnMainThread() {
base::TimeTicks IdleHelper::WillProcessIdleTask() {
helper_->CheckOnValidThread();
- DCHECK(IsInIdlePeriod(state_.idle_period_state()));
-
state_.TraceIdleIdleTaskStart();
return CurrentIdleTaskDeadline();
}
@@ -337,7 +323,8 @@ IdleHelper::State::State(SchedulerHelper* helper,
: helper_(helper),
delegate_(delegate),
idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD),
- nestable_events_started_(false),
+ idle_period_trace_event_started_(false),
+ running_idle_task_for_tracing_(false),
tracing_category_(tracing_category),
disabled_by_default_tracing_category_(
disabled_by_default_tracing_category),
@@ -372,9 +359,11 @@ void IdleHelper::State::UpdateState(IdlePeriodState new_state,
TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing);
if (is_tracing) {
base::TimeTicks now(optional_now.is_null() ? helper_->Now() : optional_now);
- TraceEventIdlePeriodStateChange(new_state, new_deadline, now);
- idle_period_deadline_for_tracing_ =
- base::TraceTicks::Now() + (new_deadline - now);
+ base::TraceTicks trace_now = base::TraceTicks::Now();
+ idle_period_deadline_for_tracing_ = trace_now + (new_deadline - now);
+ TraceEventIdlePeriodStateChange(
+ new_state, running_idle_task_for_tracing_,
+ idle_period_deadline_for_tracing_, trace_now);
}
idle_period_state_ = new_state;
@@ -394,11 +383,10 @@ void IdleHelper::State::TraceIdleIdleTaskStart() {
bool is_tracing;
TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing);
- if (is_tracing && nestable_events_started_) {
- last_idle_task_trace_time_ = base::TraceTicks::Now();
- TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
- tracing_category_, "RunningIdleTask", this,
- last_idle_task_trace_time_.ToInternalValue());
+ if (is_tracing) {
+ TraceEventIdlePeriodStateChange(
+ idle_period_state_, true, idle_period_deadline_for_tracing_,
+ base::TraceTicks::Now());
}
}
@@ -407,69 +395,67 @@ void IdleHelper::State::TraceIdleIdleTaskEnd() {
bool is_tracing;
TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing);
- if (is_tracing && nestable_events_started_) {
- if (!idle_period_deadline_for_tracing_.is_null() &&
- base::TraceTicks::Now() > idle_period_deadline_for_tracing_) {
- TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
- tracing_category_, "DeadlineOverrun", this,
- std::max(idle_period_deadline_for_tracing_,
- last_idle_task_trace_time_).ToInternalValue());
- TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "DeadlineOverrun",
- this);
- }
- TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "RunningIdleTask", this);
+ if (is_tracing) {
+ TraceEventIdlePeriodStateChange(
+ idle_period_state_, false, idle_period_deadline_for_tracing_,
+ base::TraceTicks::Now());
}
}
void IdleHelper::State::TraceEventIdlePeriodStateChange(
IdlePeriodState new_state,
- base::TimeTicks new_deadline,
- base::TimeTicks now) {
+ bool new_running_idle_task,
+ base::TraceTicks new_deadline,
+ base::TraceTicks now) {
TRACE_EVENT2(disabled_by_default_tracing_category_, "SetIdlePeriodState",
"old_state",
IdleHelper::IdlePeriodStateToString(idle_period_state_),
"new_state", IdleHelper::IdlePeriodStateToString(new_state));
- if (nestable_events_started_) {
- // End async tracing events for the state we are leaving.
- if (idle_period_state_ == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) {
- TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "LongIdlePeriodPaused",
- this);
- }
- if (IsInLongIdlePeriod(idle_period_state_) &&
- !IsInLongIdlePeriod(new_state)) {
- TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "LongIdlePeriod",
- this);
- }
- if (idle_period_state_ == IdlePeriodState::IN_SHORT_IDLE_PERIOD) {
- TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_, "ShortIdlePeriod",
- this);
- }
- if (IsInIdlePeriod(idle_period_state_) && !IsInIdlePeriod(new_state)) {
- TRACE_EVENT_NESTABLE_ASYNC_END0(tracing_category_,
- idle_period_tracing_name_, this);
- nestable_events_started_ = false;
+
+ if (idle_period_trace_event_started_ && running_idle_task_for_tracing_ &&
+ !new_running_idle_task) {
+ running_idle_task_for_tracing_ = false;
+ if (!idle_period_deadline_for_tracing_.is_null() &&
+ now > idle_period_deadline_for_tracing_) {
+ TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(
+ tracing_category_, idle_period_tracing_name_, this,
+ "DeadlineOverrun",
+ std::max(idle_period_deadline_for_tracing_,
+ last_idle_task_trace_time_).ToInternalValue());
}
}
- // Start async tracing events for the state we are entering.
- if (IsInIdlePeriod(new_state) && !IsInIdlePeriod(idle_period_state_)) {
- nestable_events_started_ = true;
- TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
- tracing_category_, idle_period_tracing_name_, this,
- "idle_period_length_ms", (new_deadline - now).ToInternalValue());
- }
- if (new_state == IdlePeriodState::IN_SHORT_IDLE_PERIOD) {
- TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(tracing_category_, "ShortIdlePeriod",
- this);
- }
- if (IsInLongIdlePeriod(new_state) &&
- !IsInLongIdlePeriod(idle_period_state_)) {
- TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(tracing_category_, "LongIdlePeriod",
- this);
- }
- if (new_state == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) {
- TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(tracing_category_, "LongIdlePeriodPaused",
- this);
+ if (IsInIdlePeriod(new_state)) {
+ if (!idle_period_trace_event_started_) {
+ idle_period_trace_event_started_ = true;
+ TRACE_EVENT_ASYNC_BEGIN1(
+ tracing_category_, idle_period_tracing_name_, this,
+ "idle_period_length_ms", (new_deadline - now).ToInternalValue());
+ }
+
+ if (new_running_idle_task) {
+ last_idle_task_trace_time_ = now;
+ running_idle_task_for_tracing_ = true;
+ TRACE_EVENT_ASYNC_STEP_INTO0(
+ tracing_category_, idle_period_tracing_name_, this,
+ "RunningIdleTask");
+ } else if (new_state == IdlePeriodState::IN_SHORT_IDLE_PERIOD) {
+ TRACE_EVENT_ASYNC_STEP_INTO0(
+ tracing_category_, idle_period_tracing_name_, this,
+ "ShortIdlePeriod");
+ } else if (IsInLongIdlePeriod(new_state) &&
+ new_state != IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) {
+ TRACE_EVENT_ASYNC_STEP_INTO0(
+ tracing_category_, idle_period_tracing_name_, this,
+ "LongIdlePeriod");
+ } else if (new_state == IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED) {
+ TRACE_EVENT_ASYNC_STEP_INTO0(
+ tracing_category_, idle_period_tracing_name_, this,
+ "LongIdlePeriodPaused");
+ }
+ } else if (idle_period_trace_event_started_) {
+ idle_period_trace_event_started_ = false;
+ TRACE_EVENT_ASYNC_END0(tracing_category_, idle_period_tracing_name_, this);
}
}
diff --git a/chromium/components/scheduler/child/idle_helper.h b/chromium/components/scheduler/child/idle_helper.h
index fb59fd2b91d..37ef636d23e 100644
--- a/chromium/components/scheduler/child/idle_helper.h
+++ b/chromium/components/scheduler/child/idle_helper.h
@@ -6,8 +6,8 @@
#define COMPONENTS_SCHEDULER_CHILD_IDLE_HELPER_H_
#include "base/message_loop/message_loop.h"
-#include "components/scheduler/child/cancelable_closure_holder.h"
-#include "components/scheduler/child/prioritizing_task_queue_selector.h"
+#include "components/scheduler/base/cancelable_closure_holder.h"
+#include "components/scheduler/base/task_queue_selector.h"
#include "components/scheduler/child/scheduler_helper.h"
#include "components/scheduler/child/single_thread_idle_task_runner.h"
#include "components/scheduler/scheduler_export.h"
@@ -68,7 +68,6 @@ class SCHEDULER_EXPORT IdleHelper
IdleHelper(
SchedulerHelper* helper,
Delegate* delegate,
- size_t idle_queue_index,
const char* tracing_category,
const char* disabled_by_default_tracing_category,
const char* idle_period_tracing_name,
@@ -147,11 +146,13 @@ class SCHEDULER_EXPORT IdleHelper
void TraceIdleIdleTaskStart();
void TraceIdleIdleTaskEnd();
- void TraceEventIdlePeriodStateChange(IdlePeriodState new_state,
- base::TimeTicks new_deadline,
- base::TimeTicks optional_now);
private:
+ void TraceEventIdlePeriodStateChange(IdlePeriodState new_state,
+ bool new_running_idle_task,
+ base::TraceTicks new_deadline,
+ base::TraceTicks optional_now);
+
SchedulerHelper* helper_; // NOT OWNED
Delegate* delegate_; // NOT OWNED
@@ -160,7 +161,8 @@ class SCHEDULER_EXPORT IdleHelper
base::TraceTicks idle_period_deadline_for_tracing_;
base::TraceTicks last_idle_task_trace_time_;
- bool nestable_events_started_;
+ bool idle_period_trace_event_started_;
+ bool running_idle_task_for_tracing_;
const char* tracing_category_;
const char* disabled_by_default_tracing_category_;
const char* idle_period_tracing_name_;
@@ -196,7 +198,7 @@ class SCHEDULER_EXPORT IdleHelper
SchedulerHelper* helper_; // NOT OWNED
Delegate* delegate_; // NOT OWNED
- size_t idle_queue_index_;
+ scoped_refptr<TaskQueue> idle_queue_;
scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
CancelableClosureHolder enable_next_long_idle_period_closure_;
@@ -204,9 +206,6 @@ class SCHEDULER_EXPORT IdleHelper
State state_;
- // A bitmap which controls the set of queues that are checked for quiescence
- // before triggering a long idle period.
- uint64 quiescence_monitored_task_queue_mask_;
base::TimeDelta required_quiescence_duration_before_long_idle_period_;
const char* disabled_by_default_tracing_category_;
diff --git a/chromium/components/scheduler/child/idle_helper_unittest.cc b/chromium/components/scheduler/child/idle_helper_unittest.cc
index 5c01ab84765..5e7f17c7279 100644
--- a/chromium/components/scheduler/child/idle_helper_unittest.cc
+++ b/chromium/components/scheduler/child/idle_helper_unittest.cc
@@ -7,12 +7,12 @@
#include "base/callback.h"
#include "base/test/simple_test_tick_clock.h"
#include "cc/test/ordered_simple_task_runner.h"
-#include "components/scheduler/child/nestable_task_runner_for_test.h"
+#include "components/scheduler/base/task_queue.h"
+#include "components/scheduler/base/task_queue_manager.h"
+#include "components/scheduler/base/test_time_source.h"
#include "components/scheduler/child/scheduler_helper.h"
-#include "components/scheduler/child/scheduler_message_loop_delegate.h"
-#include "components/scheduler/child/task_queue.h"
-#include "components/scheduler/child/task_queue_manager.h"
-#include "components/scheduler/child/test_time_source.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate_for_test.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -126,14 +126,13 @@ void EndIdlePeriodIdleTask(IdleHelper* idle_helper, base::TimeTicks deadline) {
idle_helper->EndIdlePeriod();
}
-scoped_refptr<NestableSingleThreadTaskRunner>
-CreateNestableSingleThreadTaskRunner(
+scoped_refptr<SchedulerTaskRunnerDelegate> CreateTaskRunnerDelegate(
base::MessageLoop* message_loop,
scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner) {
if (message_loop)
- return SchedulerMessageLoopDelegate::Create(message_loop);
+ return SchedulerTaskRunnerDelegateImpl::Create(message_loop);
- return NestableTaskRunnerForTest::Create(mock_task_runner);
+ return SchedulerTaskRunnerDelegateForTest::Create(mock_task_runner);
}
}; // namespace
@@ -145,7 +144,6 @@ class IdleHelperForTest : public IdleHelper, public IdleHelper::Delegate {
base::TimeDelta required_quiescence_duration_before_long_idle_period)
: IdleHelper(scheduler_helper,
this,
- SchedulerHelper::TASK_QUEUE_COUNT,
"test.idle",
TRACE_DISABLED_BY_DEFAULT("test.idle"),
"TestSchedulerIdlePeriod",
@@ -174,15 +172,13 @@ class BaseIdleHelperTest : public testing::Test {
? nullptr
: new cc::OrderedSimpleTaskRunner(clock_.get(), false)),
message_loop_(message_loop),
- nestable_task_runner_(
- CreateNestableSingleThreadTaskRunner(message_loop,
- mock_task_runner_)),
+ main_task_runner_(
+ CreateTaskRunnerDelegate(message_loop, mock_task_runner_)),
scheduler_helper_(
- new SchedulerHelper(nestable_task_runner_,
+ new SchedulerHelper(main_task_runner_,
"test.idle",
TRACE_DISABLED_BY_DEFAULT("test.idle"),
- TRACE_DISABLED_BY_DEFAULT("test.idle.debug"),
- SchedulerHelper::TASK_QUEUE_COUNT + 1)),
+ TRACE_DISABLED_BY_DEFAULT("test.idle.debug"))),
idle_helper_(new IdleHelperForTest(
scheduler_helper_.get(),
required_quiescence_duration_before_long_idle_period)),
@@ -278,7 +274,7 @@ class BaseIdleHelperTest : public testing::Test {
scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
scoped_ptr<base::MessageLoop> message_loop_;
- scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner_;
scoped_ptr<SchedulerHelper> scheduler_helper_;
scoped_ptr<IdleHelperForTest> idle_helper_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
@@ -828,7 +824,7 @@ TEST_F(IdleHelperTest, TestLongIdlePeriodRestartWaitsIfNotMaxDeadline) {
// Once the pending task is run the new idle period should start.
clock_->Advance(pending_task_delay - idle_task_duration);
- RunUntilIdle();
+
// Since the idle period tried to start before the pending task ran we have to
// wait for the idle helper to retry starting the long idle period.
clock_->Advance(retry_enable_long_idle_period_delay());
diff --git a/chromium/components/scheduler/child/nestable_task_runner_for_test.cc b/chromium/components/scheduler/child/nestable_task_runner_for_test.cc
deleted file mode 100644
index 5bcfde816db..00000000000
--- a/chromium/components/scheduler/child/nestable_task_runner_for_test.cc
+++ /dev/null
@@ -1,83 +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/scheduler/child/nestable_task_runner_for_test.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-
-namespace scheduler {
-
-// static
-scoped_refptr<NestableTaskRunnerForTest> NestableTaskRunnerForTest::Create(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- return make_scoped_refptr(new NestableTaskRunnerForTest(task_runner));
-}
-
-NestableTaskRunnerForTest::NestableTaskRunnerForTest(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : task_runner_(task_runner), is_nested_(false), weak_factory_(this) {
- weak_nestable_task_runner_ptr_ = weak_factory_.GetWeakPtr();
-}
-
-NestableTaskRunnerForTest::~NestableTaskRunnerForTest() {
-}
-
-void NestableTaskRunnerForTest::WrapTask(
- const base::PendingTask* wrapped_task) {
- scoped_refptr<NestableTaskRunnerForTest> protect(this);
- FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_,
- DidProcessTask(*wrapped_task));
- wrapped_task->task.Run();
- FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_,
- WillProcessTask(*wrapped_task));
-}
-
-bool NestableTaskRunnerForTest::PostDelayedTask(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- base::PendingTask* wrapped_task = new base::PendingTask(from_here, task);
- return task_runner_->PostDelayedTask(
- from_here,
- base::Bind(&NestableTaskRunnerForTest::WrapTask,
- weak_nestable_task_runner_ptr_, base::Owned(wrapped_task)),
- delay);
-}
-
-bool NestableTaskRunnerForTest::PostNonNestableDelayedTask(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- base::PendingTask* wrapped_task = new base::PendingTask(from_here, task);
- return task_runner_->PostNonNestableDelayedTask(
- from_here,
- base::Bind(&NestableTaskRunnerForTest::WrapTask,
- weak_nestable_task_runner_ptr_, base::Owned(wrapped_task)),
- delay);
-}
-
-bool NestableTaskRunnerForTest::RunsTasksOnCurrentThread() const {
- return task_runner_->RunsTasksOnCurrentThread();
-}
-
-bool NestableTaskRunnerForTest::IsNested() const {
- return is_nested_;
-}
-
-void NestableTaskRunnerForTest::SetNested(bool is_nested) {
- is_nested_ = is_nested;
-}
-
-void NestableTaskRunnerForTest::AddTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- task_observers_.AddObserver(task_observer);
-}
-
-void NestableTaskRunnerForTest::RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- task_observers_.RemoveObserver(task_observer);
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/child/null_idle_task_runner.cc b/chromium/components/scheduler/child/null_idle_task_runner.cc
deleted file mode 100644
index 934b3492c9c..00000000000
--- a/chromium/components/scheduler/child/null_idle_task_runner.cc
+++ /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/scheduler/child/null_idle_task_runner.h"
-
-namespace scheduler {
-
-NullIdleTaskRunner::NullIdleTaskRunner()
- : SingleThreadIdleTaskRunner(nullptr, nullptr, nullptr, "null.taskrunner") {
-}
-
-NullIdleTaskRunner::~NullIdleTaskRunner() {
-}
-
-void NullIdleTaskRunner::PostIdleTask(
- const tracked_objects::Location& from_here,
- const IdleTask& idle_task) {
-}
-
-void NullIdleTaskRunner::PostNonNestableIdleTask(
- const tracked_objects::Location& from_here,
- const IdleTask& idle_task) {
-}
-
-void NullIdleTaskRunner::PostIdleTaskAfterWakeup(
- const tracked_objects::Location& from_here,
- const IdleTask& idle_task) {
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/child/null_idle_task_runner.h b/chromium/components/scheduler/child/null_idle_task_runner.h
deleted file mode 100644
index 734d0c152ce..00000000000
--- a/chromium/components/scheduler/child/null_idle_task_runner.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SCHEDULER_CHILD_NULL_IDLE_TASK_RUNNER_H_
-#define COMPONENTS_SCHEDULER_CHILD_NULL_IDLE_TASK_RUNNER_H_
-
-#include "components/scheduler/child/single_thread_idle_task_runner.h"
-
-namespace scheduler {
-
-class NullIdleTaskRunner : public SingleThreadIdleTaskRunner {
- public:
- NullIdleTaskRunner();
- void PostIdleTask(const tracked_objects::Location& from_here,
- const IdleTask& idle_task) override;
-
- void PostNonNestableIdleTask(const tracked_objects::Location& from_here,
- const IdleTask& idle_task) override;
-
- void PostIdleTaskAfterWakeup(const tracked_objects::Location& from_here,
- const IdleTask& idle_task) override;
-
- protected:
- ~NullIdleTaskRunner() override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(NullIdleTaskRunner);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_CHILD_NULL_IDLE_TASK_RUNNER_H_
diff --git a/chromium/components/scheduler/child/null_task_queue.cc b/chromium/components/scheduler/child/null_task_queue.cc
deleted file mode 100644
index ef5bab5095e..00000000000
--- a/chromium/components/scheduler/child/null_task_queue.cc
+++ /dev/null
@@ -1,41 +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/scheduler/child/null_task_queue.h"
-
-namespace scheduler {
-
-NullTaskQueue::NullTaskQueue(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : task_runner_(task_runner) {}
-
-NullTaskQueue::~NullTaskQueue() {}
-
-bool NullTaskQueue::RunsTasksOnCurrentThread() const {
- return task_runner_->RunsTasksOnCurrentThread();
-}
-
-bool NullTaskQueue::PostDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- return task_runner_->PostDelayedTask(from_here, task, delay);
-}
-
-bool NullTaskQueue::PostNonNestableDelayedTask(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- return task_runner_->PostNonNestableDelayedTask(from_here, task, delay);
-}
-bool NullTaskQueue::PostDelayedTaskAt(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeTicks desired_run_time) {
- // Note: this loses the guarantee of monotonicity but we can't do any better
- // with base::TaskRunner.
- return task_runner_->PostDelayedTask(
- from_here, task, desired_run_time - base::TimeTicks::Now());
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/child/null_task_queue.h b/chromium/components/scheduler/child/null_task_queue.h
deleted file mode 100644
index 7c4e5d8adfb..00000000000
--- a/chromium/components/scheduler/child/null_task_queue.h
+++ /dev/null
@@ -1,39 +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_SCHEDULER_NULL_CHILD_TASK_QUEUE_H_
-#define COMPONENTS_SCHEDULER_NULL_CHILD_TASK_QUEUE_H_
-
-#include "components/scheduler/child/task_queue.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-
-class SCHEDULER_EXPORT NullTaskQueue : public TaskQueue {
- public:
- NullTaskQueue(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
- // TaskQueue implementation
- bool RunsTasksOnCurrentThread() const override;
- bool PostDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) override;
- bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) override;
- bool PostDelayedTaskAt(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeTicks desired_run_time) override;
-
- protected:
- ~NullTaskQueue() override;
-
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(NullTaskQueue);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_CHILD_NULL_TASK_QUEUE_H_
diff --git a/chromium/components/scheduler/child/null_worker_scheduler.cc b/chromium/components/scheduler/child/null_worker_scheduler.cc
deleted file mode 100644
index 3f0a7cd09c1..00000000000
--- a/chromium/components/scheduler/child/null_worker_scheduler.cc
+++ /dev/null
@@ -1,55 +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/scheduler/child/null_worker_scheduler.h"
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/thread_task_runner_handle.h"
-#include "components/scheduler/child/null_idle_task_runner.h"
-#include "components/scheduler/child/null_task_queue.h"
-
-namespace scheduler {
-
-NullWorkerScheduler::NullWorkerScheduler()
- : task_runner_(new NullTaskQueue(base::ThreadTaskRunnerHandle::Get())),
- idle_task_runner_(new NullIdleTaskRunner()) {}
-
-NullWorkerScheduler::~NullWorkerScheduler() {
-}
-
-scoped_refptr<TaskQueue> NullWorkerScheduler::DefaultTaskRunner() {
- return task_runner_;
-}
-
-scoped_refptr<SingleThreadIdleTaskRunner>
-NullWorkerScheduler::IdleTaskRunner() {
- return idle_task_runner_;
-}
-
-void NullWorkerScheduler::AddTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- base::MessageLoop::current()->AddTaskObserver(task_observer);
-}
-
-void NullWorkerScheduler::RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- base::MessageLoop::current()->RemoveTaskObserver(task_observer);
-}
-
-bool NullWorkerScheduler::CanExceedIdleDeadlineIfRequired() const {
- return false;
-}
-
-bool NullWorkerScheduler::ShouldYieldForHighPriorityWork() {
- return false;
-}
-
-void NullWorkerScheduler::Init() {
-}
-
-void NullWorkerScheduler::Shutdown() {
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/child/null_worker_scheduler.h b/chromium/components/scheduler/child/null_worker_scheduler.h
deleted file mode 100644
index 4e0daae131d..00000000000
--- a/chromium/components/scheduler/child/null_worker_scheduler.h
+++ /dev/null
@@ -1,37 +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_SCHEDULER_CHILD_NULL_WORKER_SCHEDULER_H_
-#define COMPONENTS_SCHEDULER_CHILD_NULL_WORKER_SCHEDULER_H_
-
-#include "components/scheduler/child/worker_scheduler.h"
-
-namespace scheduler {
-
-class NullWorkerScheduler : public WorkerScheduler {
- public:
- NullWorkerScheduler();
- ~NullWorkerScheduler() override;
-
- scoped_refptr<TaskQueue> DefaultTaskRunner() override;
- scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override;
-
- void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
- void RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) override;
- bool CanExceedIdleDeadlineIfRequired() const override;
- bool ShouldYieldForHighPriorityWork() override;
- void Init() override;
- void Shutdown() override;
-
- private:
- scoped_refptr<TaskQueue> task_runner_;
- scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(NullWorkerScheduler);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_CHILD_NULL_WORKER_SCHEDULER_H_
diff --git a/chromium/components/scheduler/child/prioritizing_task_queue_selector.cc b/chromium/components/scheduler/child/prioritizing_task_queue_selector.cc
deleted file mode 100644
index 5275f72b65d..00000000000
--- a/chromium/components/scheduler/child/prioritizing_task_queue_selector.cc
+++ /dev/null
@@ -1,192 +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/scheduler/child/prioritizing_task_queue_selector.h"
-
-#include "base/logging.h"
-#include "base/pending_task.h"
-#include "base/trace_event/trace_event_argument.h"
-
-namespace scheduler {
-
-PrioritizingTaskQueueSelector::PrioritizingTaskQueueSelector()
- : starvation_count_(0), task_queue_selector_observer_(nullptr) {
-}
-
-PrioritizingTaskQueueSelector::~PrioritizingTaskQueueSelector() {
-}
-
-void PrioritizingTaskQueueSelector::RegisterWorkQueues(
- const std::vector<const base::TaskQueue*>& work_queues) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- work_queues_ = work_queues;
- for (auto& queue_priority : queue_priorities_) {
- queue_priority.clear();
- }
-
- // By default, all work queues are set to normal priority.
- for (size_t i = 0; i < work_queues.size(); i++) {
- queue_priorities_[NORMAL_PRIORITY].insert(i);
- }
-}
-
-void PrioritizingTaskQueueSelector::SetQueuePriority(size_t queue_index,
- QueuePriority priority) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK_LT(queue_index, work_queues_.size());
- DCHECK_LT(priority, QUEUE_PRIORITY_COUNT);
- bool previously_enabled = DisableQueueInternal(queue_index);
- queue_priorities_[priority].insert(queue_index);
- if (task_queue_selector_observer_ && !previously_enabled)
- task_queue_selector_observer_->OnTaskQueueEnabled();
-}
-
-void PrioritizingTaskQueueSelector::EnableQueue(size_t queue_index,
- QueuePriority priority) {
- SetQueuePriority(queue_index, priority);
-}
-
-void PrioritizingTaskQueueSelector::DisableQueue(size_t queue_index) {
- DisableQueueInternal(queue_index);
-}
-
-bool PrioritizingTaskQueueSelector::DisableQueueInternal(size_t queue_index) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK_LT(queue_index, work_queues_.size());
- bool previously_enabled = false;
- for (auto& queue_priority : queue_priorities_) {
- if (queue_priority.erase(queue_index))
- previously_enabled = true;
- }
- return previously_enabled;
-}
-
-bool PrioritizingTaskQueueSelector::IsQueueEnabled(size_t queue_index) const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK_LT(queue_index, work_queues_.size());
- for (const auto& queue_priority : queue_priorities_) {
- if (queue_priority.find(queue_index) != queue_priority.end())
- return true;
- }
- return false;
-}
-
-bool PrioritizingTaskQueueSelector::IsOlder(const base::TaskQueue* queueA,
- const base::TaskQueue* queueB) {
- // Note: the comparison is correct due to the fact that the PendingTask
- // operator inverts its comparison operation in order to work well in a heap
- // based priority queue.
- return queueB->front() < queueA->front();
-}
-
-PrioritizingTaskQueueSelector::QueuePriority
-PrioritizingTaskQueueSelector::NextPriority(QueuePriority priority) {
- DCHECK(priority < QUEUE_PRIORITY_COUNT);
- return static_cast<QueuePriority>(static_cast<int>(priority) + 1);
-}
-
-bool PrioritizingTaskQueueSelector::ChooseOldestWithPriority(
- QueuePriority priority,
- size_t* out_queue_index) const {
- bool found_non_empty_queue = false;
- size_t chosen_queue = 0;
- for (int queue_index : queue_priorities_[priority]) {
- if (work_queues_[queue_index]->empty()) {
- continue;
- }
- if (!found_non_empty_queue ||
- IsOlder(work_queues_[queue_index], work_queues_[chosen_queue])) {
- found_non_empty_queue = true;
- chosen_queue = queue_index;
- }
- }
-
- if (found_non_empty_queue) {
- *out_queue_index = chosen_queue;
- }
- return found_non_empty_queue;
-}
-
-bool PrioritizingTaskQueueSelector::SelectWorkQueueToService(
- size_t* out_queue_index) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK(work_queues_.size());
- // Always service the control queue if it has any work.
- if (ChooseOldestWithPriority(CONTROL_PRIORITY, out_queue_index)) {
- DidSelectQueueWithPriority(CONTROL_PRIORITY);
- return true;
- }
- // Select from the normal priority queue if we are starving it.
- if (starvation_count_ >= kMaxStarvationTasks &&
- ChooseOldestWithPriority(NORMAL_PRIORITY, out_queue_index)) {
- DidSelectQueueWithPriority(NORMAL_PRIORITY);
- return true;
- }
- // Otherwise choose in priority order.
- for (QueuePriority priority = HIGH_PRIORITY; priority < QUEUE_PRIORITY_COUNT;
- priority = NextPriority(priority)) {
- if (ChooseOldestWithPriority(priority, out_queue_index)) {
- DidSelectQueueWithPriority(priority);
- return true;
- }
- }
- return false;
-}
-
-void PrioritizingTaskQueueSelector::DidSelectQueueWithPriority(
- QueuePriority priority) {
- switch (priority) {
- case CONTROL_PRIORITY:
- break;
- case HIGH_PRIORITY:
- starvation_count_++;
- break;
- case NORMAL_PRIORITY:
- case BEST_EFFORT_PRIORITY:
- starvation_count_ = 0;
- break;
- default:
- NOTREACHED();
- }
-}
-
-// static
-const char* PrioritizingTaskQueueSelector::PriorityToString(
- QueuePriority priority) {
- switch (priority) {
- case CONTROL_PRIORITY:
- return "control";
- case HIGH_PRIORITY:
- return "high";
- case NORMAL_PRIORITY:
- return "normal";
- case BEST_EFFORT_PRIORITY:
- return "best_effort";
- default:
- NOTREACHED();
- return nullptr;
- }
-}
-
-void PrioritizingTaskQueueSelector::AsValueInto(
- base::trace_event::TracedValue* state) const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- state->BeginDictionary("priorities");
- for (QueuePriority priority = FIRST_QUEUE_PRIORITY;
- priority < QUEUE_PRIORITY_COUNT; priority = NextPriority(priority)) {
- state->BeginArray(PriorityToString(priority));
- for (size_t queue_index : queue_priorities_[priority])
- state->AppendInteger(queue_index);
- state->EndArray();
- }
- state->EndDictionary();
- state->SetInteger("starvation_count", starvation_count_);
-}
-
-void PrioritizingTaskQueueSelector::SetTaskQueueSelectorObserver(
- Observer* observer) {
- task_queue_selector_observer_ = observer;
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/child/prioritizing_task_queue_selector.h b/chromium/components/scheduler/child/prioritizing_task_queue_selector.h
deleted file mode 100644
index a9a63eb12bd..00000000000
--- a/chromium/components/scheduler/child/prioritizing_task_queue_selector.h
+++ /dev/null
@@ -1,108 +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_SCHEDULER_CHILD_PRIORITIZING_TASK_QUEUE_SELECTOR_H_
-#define COMPONENTS_SCHEDULER_CHILD_PRIORITIZING_TASK_QUEUE_SELECTOR_H_
-
-#include <set>
-
-#include "base/compiler_specific.h"
-#include "base/threading/thread_checker.h"
-#include "components/scheduler/child/task_queue_selector.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-
-// A PrioritizingTaskQueueSelector is a TaskQueueSelector which is used by the
-// SchedulerHelper to enable prioritization of particular task queues.
-class SCHEDULER_EXPORT PrioritizingTaskQueueSelector
- : NON_EXPORTED_BASE(public TaskQueueSelector) {
- public:
- enum QueuePriority {
- // Queues with control priority will run before any other queue, and will
- // explicitly starve other queues. Typically this should only be used for
- // private queues which perform control operations.
- CONTROL_PRIORITY,
- // Queues with high priority will be selected preferentially over normal or
- // best effort queues. The selector will ensure that high priority queues
- // cannot completely starve normal priority queues.
- HIGH_PRIORITY,
- // Queues with normal priority are the default.
- NORMAL_PRIORITY,
- // Queues with best effort priority will only be run if all other queues are
- // empty. They can be starved by the other queues.
- BEST_EFFORT_PRIORITY,
- // Must be the last entry.
- QUEUE_PRIORITY_COUNT,
- FIRST_QUEUE_PRIORITY = CONTROL_PRIORITY,
- };
-
- PrioritizingTaskQueueSelector();
- ~PrioritizingTaskQueueSelector() override;
-
- // Set the priority of |queue_index| to |priority|.
- void SetQueuePriority(size_t queue_index, QueuePriority priority);
-
- // Enable the |queue_index| with a priority of |priority|. By default all
- // queues are enabled with normal priority.
- void EnableQueue(size_t queue_index, QueuePriority priority);
-
- // Disable the |queue_index|.
- void DisableQueue(size_t queue_index);
-
- // Whether |queue_index| is enabled.
- bool IsQueueEnabled(size_t queue_index) const;
-
- // TaskQueueSelector implementation:
- void RegisterWorkQueues(
- const std::vector<const base::TaskQueue*>& work_queues) override;
- bool SelectWorkQueueToService(size_t* out_queue_index) override;
- void AsValueInto(base::trace_event::TracedValue* state) const override;
- void SetTaskQueueSelectorObserver(Observer* observer) override;
-
- protected:
- // Disable the |queue_index|. Returns true if the queue was previously enabled
- // otherwise returns false.
- bool DisableQueueInternal(size_t queue_index);
-
- private:
- // Returns true if queueA contains an older task than queueB.
- static bool IsOlder(const base::TaskQueue* queueA,
- const base::TaskQueue* queueB);
-
- // Returns the priority which is next after |priority|.
- static QueuePriority NextPriority(QueuePriority priority);
-
- static const char* PriorityToString(QueuePriority priority);
-
- // Return true if |out_queue_index| indicates the index of the queue with
- // the oldest pending task from the set of queues of |priority|, or
- // false if all queues of that priority are empty.
- bool ChooseOldestWithPriority(QueuePriority priority,
- size_t* out_queue_index) const;
-
- // Returns true if |queue_index| is enabled with the given |priority|.
- bool QueueEnabledWithPriority(size_t queue_index,
- QueuePriority priority) const;
-
- // Called whenever the selector chooses a task queue for execution with the
- // priority |priority|.
- void DidSelectQueueWithPriority(QueuePriority priority);
-
- // Number of high priority tasks which can be run before a normal priority
- // task should be selected to prevent starvation.
- // TODO(rmcilroy): Check if this is a good value.
- static const size_t kMaxStarvationTasks = 5;
-
- base::ThreadChecker main_thread_checker_;
- std::vector<const base::TaskQueue*> work_queues_;
- std::set<size_t> queue_priorities_[QUEUE_PRIORITY_COUNT];
- size_t starvation_count_;
- Observer* task_queue_selector_observer_; // NOT OWNED
- DISALLOW_COPY_AND_ASSIGN(PrioritizingTaskQueueSelector);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_CHILD_PRIORITIZING_TASK_QUEUE_SELECTOR_H_
diff --git a/chromium/components/scheduler/child/prioritizing_task_queue_selector_unittest.cc b/chromium/components/scheduler/child/prioritizing_task_queue_selector_unittest.cc
deleted file mode 100644
index 81a2a945e6f..00000000000
--- a/chromium/components/scheduler/child/prioritizing_task_queue_selector_unittest.cc
+++ /dev/null
@@ -1,248 +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/scheduler/child/prioritizing_task_queue_selector.h"
-
-#include "base/bind.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
-#include "base/pending_task.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace scheduler {
-
-class MockObserver : public TaskQueueSelector::Observer {
- public:
- MockObserver() {}
- virtual ~MockObserver() {}
-
- MOCK_METHOD0(OnTaskQueueEnabled, void());
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockObserver);
-};
-
-class PrioritizingTaskQueueSelectorForTest
- : public PrioritizingTaskQueueSelector {
- public:
- PrioritizingTaskQueueSelectorForTest() {}
- ~PrioritizingTaskQueueSelectorForTest() override {}
-
- using PrioritizingTaskQueueSelector::DisableQueueInternal;
-};
-
-class PrioritizingTaskQueueSelectorTest : public testing::Test {
- public:
- PrioritizingTaskQueueSelectorTest()
- : test_closure_(
- base::Bind(&PrioritizingTaskQueueSelectorTest::TestFunction)) {}
- ~PrioritizingTaskQueueSelectorTest() override {}
-
- std::vector<base::PendingTask> GetTasks(int count) {
- std::vector<base::PendingTask> tasks;
- for (int i = 0; i < count; i++) {
- base::PendingTask task = base::PendingTask(FROM_HERE, test_closure_);
- task.sequence_num = i;
- tasks.push_back(task);
- }
- return tasks;
- }
-
- void PushTasks(const std::vector<base::PendingTask>& tasks,
- const size_t queue_indices[]) {
- for (size_t i = 0; i < tasks.size(); i++) {
- task_queues_[queue_indices[i]]->push(tasks[i]);
- }
- }
-
- std::vector<size_t> PopTasks() {
- std::vector<size_t> order;
- size_t chosen_queue_index;
- while (selector_.SelectWorkQueueToService(&chosen_queue_index)) {
- order.push_back(chosen_queue_index);
- task_queues_[chosen_queue_index]->pop();
- }
- return order;
- }
-
- static void TestFunction() {}
-
- protected:
- void SetUp() final {
- std::vector<const base::TaskQueue*> const_task_queues;
- for (size_t i = 0; i < kTaskQueueCount; i++) {
- scoped_ptr<base::TaskQueue> task_queue(new base::TaskQueue());
- const_task_queues.push_back(task_queue.get());
- task_queues_.push_back(task_queue.release());
- }
- selector_.RegisterWorkQueues(const_task_queues);
- for (size_t i = 0; i < kTaskQueueCount; i++)
- EXPECT_TRUE(selector_.IsQueueEnabled(i)) << i;
- }
-
- const size_t kTaskQueueCount = 5;
- base::Closure test_closure_;
- PrioritizingTaskQueueSelectorForTest selector_;
- ScopedVector<base::TaskQueue> task_queues_;
-};
-
-TEST_F(PrioritizingTaskQueueSelectorTest, TestDefaultPriority) {
- std::vector<base::PendingTask> tasks = GetTasks(5);
- size_t queue_order[] = {4, 3, 2, 1, 0};
- PushTasks(tasks, queue_order);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(4, 3, 2, 1, 0));
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest, TestHighPriority) {
- std::vector<base::PendingTask> tasks = GetTasks(5);
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasks(tasks, queue_order);
- selector_.SetQueuePriority(2, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(2, 0, 1, 3, 4));
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest, TestBestEffortPriority) {
- std::vector<base::PendingTask> tasks = GetTasks(5);
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasks(tasks, queue_order);
- selector_.SetQueuePriority(
- 0, PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
- selector_.SetQueuePriority(2, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(2, 1, 3, 4, 0));
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest, TestControlPriority) {
- std::vector<base::PendingTask> tasks = GetTasks(5);
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasks(tasks, queue_order);
- selector_.SetQueuePriority(4,
- PrioritizingTaskQueueSelector::CONTROL_PRIORITY);
- EXPECT_TRUE(selector_.IsQueueEnabled(4));
- selector_.SetQueuePriority(2, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
- EXPECT_TRUE(selector_.IsQueueEnabled(2));
- EXPECT_THAT(PopTasks(), testing::ElementsAre(4, 2, 0, 1, 3));
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest,
- TestDisableReturnsTrueIfQueueWasEnabled) {
- selector_.EnableQueue(1, PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
- EXPECT_TRUE(selector_.DisableQueueInternal(1));
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest,
- TestDisableReturnsFalseIfQueueWasAlreadyDisabled) {
- selector_.DisableQueue(1);
- EXPECT_FALSE(selector_.DisableQueueInternal(1));
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest, TestDisableEnable) {
- MockObserver mock_observer;
- selector_.SetTaskQueueSelectorObserver(&mock_observer);
-
- std::vector<base::PendingTask> tasks = GetTasks(5);
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasks(tasks, queue_order);
- selector_.DisableQueue(2);
- EXPECT_FALSE(selector_.IsQueueEnabled(2));
- selector_.DisableQueue(4);
- EXPECT_FALSE(selector_.IsQueueEnabled(4));
- EXPECT_THAT(PopTasks(), testing::ElementsAre(0, 1, 3));
-
- EXPECT_CALL(mock_observer, OnTaskQueueEnabled()).Times(2);
- selector_.EnableQueue(2, PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(2));
- selector_.EnableQueue(4, PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(4));
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest, TestEmptyQueues) {
- size_t chosen_queue_index = 0;
- EXPECT_FALSE(selector_.SelectWorkQueueToService(&chosen_queue_index));
-
- // Test only disabled queues.
- std::vector<base::PendingTask> tasks = GetTasks(1);
- size_t queue_order[] = {0};
- PushTasks(tasks, queue_order);
- selector_.DisableQueue(0);
- EXPECT_FALSE(selector_.IsQueueEnabled(0));
- EXPECT_FALSE(selector_.SelectWorkQueueToService(&chosen_queue_index));
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest, TestDelay) {
- std::vector<base::PendingTask> tasks = GetTasks(5);
- tasks[0].delayed_run_time =
- base::TimeTicks() + base::TimeDelta::FromMilliseconds(200);
- tasks[3].delayed_run_time =
- base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
- size_t queue_order[] = {0, 1, 2, 3, 4};
- PushTasks(tasks, queue_order);
- EXPECT_THAT(PopTasks(), testing::ElementsAre(1, 2, 4, 3, 0));
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest, TestControlStarvesOthers) {
- std::vector<base::PendingTask> tasks = GetTasks(4);
- size_t queue_order[] = {0, 1, 2, 3};
- PushTasks(tasks, queue_order);
- selector_.SetQueuePriority(3,
- PrioritizingTaskQueueSelector::CONTROL_PRIORITY);
- selector_.SetQueuePriority(2, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
- selector_.SetQueuePriority(
- 1, PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
- for (int i = 0; i < 100; i++) {
- size_t chosen_queue_index = 0;
- EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_queue_index));
- EXPECT_EQ(3ul, chosen_queue_index);
- // Don't remove task from queue to simulate all queues still being full.
- }
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest, TestHighPriorityDoesNotStarveNormal) {
- std::vector<base::PendingTask> tasks = GetTasks(3);
- size_t queue_order[] = {0, 1, 2};
- PushTasks(tasks, queue_order);
- selector_.SetQueuePriority(2, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
- selector_.SetQueuePriority(
- 1, PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
- size_t counts[] = {0, 0, 0};
- for (int i = 0; i < 100; i++) {
- size_t chosen_queue_index = 0;
- EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_queue_index));
- counts[chosen_queue_index]++;
- // Don't remove task from queue to simulate all queues still being full.
- }
- EXPECT_GT(counts[0], 0ul); // Check high doesn't starve normal.
- EXPECT_GT(counts[2], counts[0]); // Check high gets more chance to run.
- EXPECT_EQ(0ul, counts[1]); // Check best effort is starved.
-}
-
-TEST_F(PrioritizingTaskQueueSelectorTest, TestBestEffortGetsStarved) {
- std::vector<base::PendingTask> tasks = GetTasks(2);
- size_t queue_order[] = {0, 1};
- PushTasks(tasks, queue_order);
- selector_.SetQueuePriority(
- 0, PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
- selector_.SetQueuePriority(1, PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
- size_t chosen_queue_index = 0;
- for (int i = 0; i < 100; i++) {
- EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_queue_index));
- EXPECT_EQ(1ul, chosen_queue_index);
- // Don't remove task from queue to simulate all queues still being full.
- }
- selector_.SetQueuePriority(1, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
- for (int i = 0; i < 100; i++) {
- EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_queue_index));
- EXPECT_EQ(1ul, chosen_queue_index);
- // Don't remove task from queue to simulate all queues still being full.
- }
- selector_.SetQueuePriority(1,
- PrioritizingTaskQueueSelector::CONTROL_PRIORITY);
- for (int i = 0; i < 100; i++) {
- EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_queue_index));
- EXPECT_EQ(1ul, chosen_queue_index);
- // Don't remove task from queue to simulate all queues still being full.
- }
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/child/scheduler_helper.cc b/chromium/components/scheduler/child/scheduler_helper.cc
index eb93a0821fc..67f9c0bf1e2 100644
--- a/chromium/components/scheduler/child/scheduler_helper.cc
+++ b/chromium/components/scheduler/child/scheduler_helper.cc
@@ -7,72 +7,62 @@
#include "base/time/default_tick_clock.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
-#include "components/scheduler/child/nestable_single_thread_task_runner.h"
-#include "components/scheduler/child/task_queue.h"
+#include "components/scheduler/base/task_queue_impl.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate.h"
namespace scheduler {
SchedulerHelper::SchedulerHelper(
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner,
const char* tracing_category,
const char* disabled_by_default_tracing_category,
- const char* disabled_by_default_verbose_tracing_category,
- size_t total_task_queue_count)
- : task_queue_selector_(new PrioritizingTaskQueueSelector()),
+ const char* disabled_by_default_verbose_tracing_category)
+ : main_task_runner_(main_task_runner),
task_queue_manager_(
- new TaskQueueManager(total_task_queue_count,
- main_task_runner,
- task_queue_selector_.get(),
+ new TaskQueueManager(main_task_runner,
disabled_by_default_tracing_category,
disabled_by_default_verbose_tracing_category)),
- quiescence_monitored_task_queue_mask_(
- ((1ull << total_task_queue_count) - 1ull) &
- ~(1ull << QueueId::CONTROL_TASK_QUEUE) &
- ~(1ull << QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE)),
- control_task_runner_(
- task_queue_manager_->TaskRunnerForQueue(QueueId::CONTROL_TASK_QUEUE)),
- control_after_wakeup_task_runner_(task_queue_manager_->TaskRunnerForQueue(
- QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE)),
- default_task_runner_(
- task_queue_manager_->TaskRunnerForQueue(QueueId::DEFAULT_TASK_QUEUE)),
+ control_task_runner_(NewTaskQueue(
+ TaskQueue::Spec("control_tq")
+ .SetWakeupPolicy(TaskQueue::WakeupPolicy::DONT_WAKE_OTHER_QUEUES)
+ .SetShouldNotifyObservers(false))),
+ control_after_wakeup_task_runner_(NewTaskQueue(
+ TaskQueue::Spec("control_after_wakeup_tq")
+ .SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP)
+ .SetWakeupPolicy(TaskQueue::WakeupPolicy::DONT_WAKE_OTHER_QUEUES)
+ .SetShouldNotifyObservers(false))),
+ default_task_runner_(NewTaskQueue(TaskQueue::Spec("default_tq")
+ .SetShouldMonitorQuiescence(true))),
time_source_(new base::DefaultTickClock),
+ observer_(nullptr),
tracing_category_(tracing_category),
disabled_by_default_tracing_category_(
disabled_by_default_tracing_category) {
- DCHECK_GE(total_task_queue_count,
- static_cast<size_t>(QueueId::TASK_QUEUE_COUNT));
- task_queue_selector_->SetQueuePriority(
- QueueId::CONTROL_TASK_QUEUE,
- PrioritizingTaskQueueSelector::CONTROL_PRIORITY);
- task_queue_manager_->SetWakeupPolicy(
- QueueId::CONTROL_TASK_QUEUE,
- TaskQueueManager::WakeupPolicy::DONT_WAKE_OTHER_QUEUES);
-
- task_queue_selector_->SetQueuePriority(
- QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE,
- PrioritizingTaskQueueSelector::CONTROL_PRIORITY);
- task_queue_manager_->SetPumpPolicy(
- QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE,
- TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
- task_queue_manager_->SetWakeupPolicy(
- QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE,
- TaskQueueManager::WakeupPolicy::DONT_WAKE_OTHER_QUEUES);
-
- for (size_t i = 0; i < TASK_QUEUE_COUNT; i++) {
- task_queue_manager_->SetQueueName(
- i, TaskQueueIdToString(static_cast<QueueId>(i)));
- }
-
- // TODO(skyostil): Increase this to 4 (crbug.com/444764).
- task_queue_manager_->SetWorkBatchSize(1);
+ control_task_runner_->SetQueuePriority(TaskQueue::CONTROL_PRIORITY);
+ control_after_wakeup_task_runner_->SetQueuePriority(
+ TaskQueue::CONTROL_PRIORITY);
+
+ task_queue_manager_->SetWorkBatchSize(4);
+
+ main_task_runner_->SetDefaultTaskRunner(default_task_runner_.get());
}
SchedulerHelper::~SchedulerHelper() {
+ Shutdown();
}
void SchedulerHelper::Shutdown() {
CheckOnValidThread();
+ if (task_queue_manager_)
+ task_queue_manager_->SetObserver(nullptr);
task_queue_manager_.reset();
+ main_task_runner_->RestoreDefaultTaskRunner();
+}
+
+scoped_refptr<TaskQueue> SchedulerHelper::NewTaskQueue(
+ const TaskQueue::Spec& spec) {
+ DCHECK(task_queue_manager_.get());
+ return task_queue_manager_->NewTaskQueue(spec);
}
scoped_refptr<TaskQueue> SchedulerHelper::DefaultTaskRunner() {
@@ -80,13 +70,11 @@ scoped_refptr<TaskQueue> SchedulerHelper::DefaultTaskRunner() {
return default_task_runner_;
}
-scoped_refptr<base::SingleThreadTaskRunner>
-SchedulerHelper::ControlTaskRunner() {
+scoped_refptr<TaskQueue> SchedulerHelper::ControlTaskRunner() {
return control_task_runner_;
}
-scoped_refptr<base::SingleThreadTaskRunner>
-SchedulerHelper::ControlAfterWakeUpTaskRunner() {
+scoped_refptr<TaskQueue> SchedulerHelper::ControlAfterWakeUpTaskRunner() {
return control_after_wakeup_task_runner_;
}
@@ -98,6 +86,7 @@ void SchedulerHelper::SetTimeSourceForTesting(
void SchedulerHelper::SetWorkBatchSizeForTesting(size_t work_batch_size) {
CheckOnValidThread();
+ DCHECK(task_queue_manager_.get());
task_queue_manager_->SetWorkBatchSize(work_batch_size);
}
@@ -110,98 +99,16 @@ base::TimeTicks SchedulerHelper::Now() const {
return time_source_->NowTicks();
}
-scoped_refptr<TaskQueue> SchedulerHelper::TaskRunnerForQueue(
- size_t queue_index) const {
- CheckOnValidThread();
- return task_queue_manager_->TaskRunnerForQueue(queue_index);
-}
-
base::TimeTicks SchedulerHelper::NextPendingDelayedTaskRunTime() const {
CheckOnValidThread();
+ DCHECK(task_queue_manager_.get());
return task_queue_manager_->NextPendingDelayedTaskRunTime();
}
-void SchedulerHelper::SetQueueName(size_t queue_index, const char* name) {
- CheckOnValidThread();
- task_queue_manager_->SetQueueName(queue_index, name);
-}
-
-bool SchedulerHelper::IsQueueEmpty(size_t queue_index) const {
- CheckOnValidThread();
- return task_queue_manager_->IsQueueEmpty(queue_index);
-}
-
-TaskQueueManager::QueueState SchedulerHelper::GetQueueState(size_t queue_index)
- const {
- CheckOnValidThread();
- return task_queue_manager_->GetQueueState(queue_index);
-}
-
-void SchedulerHelper::SetQueuePriority(
- size_t queue_index,
- PrioritizingTaskQueueSelector::QueuePriority priority) {
- CheckOnValidThread();
- return task_queue_selector_->SetQueuePriority(queue_index, priority);
-}
-
-void SchedulerHelper::EnableQueue(
- size_t queue_index,
- PrioritizingTaskQueueSelector::QueuePriority priority) {
- CheckOnValidThread();
- task_queue_selector_->EnableQueue(queue_index, priority);
-}
-
-void SchedulerHelper::DisableQueue(size_t queue_index) {
- CheckOnValidThread();
- task_queue_selector_->DisableQueue(queue_index);
-}
-
-bool SchedulerHelper::IsQueueEnabled(size_t queue_index) const {
- CheckOnValidThread();
- return task_queue_selector_->IsQueueEnabled(queue_index);
-}
-
-void SchedulerHelper::SetPumpPolicy(size_t queue_index,
- TaskQueueManager::PumpPolicy pump_policy) {
- CheckOnValidThread();
- return task_queue_manager_->SetPumpPolicy(queue_index, pump_policy);
-}
-
-void SchedulerHelper::SetWakeupPolicy(
- size_t queue_index,
- TaskQueueManager::WakeupPolicy wakeup_policy) {
- CheckOnValidThread();
- return task_queue_manager_->SetWakeupPolicy(queue_index, wakeup_policy);
-}
-
-void SchedulerHelper::PumpQueue(size_t queue_index) {
- CheckOnValidThread();
- return task_queue_manager_->PumpQueue(queue_index);
-}
-
-uint64 SchedulerHelper::GetQuiescenceMonitoredTaskQueueMask() const {
- CheckOnValidThread();
- return quiescence_monitored_task_queue_mask_;
-}
-
-uint64 SchedulerHelper::GetAndClearTaskWasRunOnQueueBitmap() {
+bool SchedulerHelper::GetAndClearSystemIsQuiescentBit() {
CheckOnValidThread();
- return task_queue_manager_->GetAndClearTaskWasRunOnQueueBitmap();
-}
-
-// static
-const char* SchedulerHelper::TaskQueueIdToString(QueueId queue_id) {
- switch (queue_id) {
- case DEFAULT_TASK_QUEUE:
- return "default_tq";
- case CONTROL_TASK_QUEUE:
- return "control_tq";
- case CONTROL_TASK_AFTER_WAKEUP_QUEUE:
- return "control_after_wakeup_tq";
- default:
- NOTREACHED();
- return nullptr;
- }
+ DCHECK(task_queue_manager_.get());
+ return task_queue_manager_->GetAndClearSystemIsQuiescentBit();
}
void SchedulerHelper::AddTaskObserver(
@@ -218,4 +125,17 @@ void SchedulerHelper::RemoveTaskObserver(
task_queue_manager_->RemoveTaskObserver(task_observer);
}
+void SchedulerHelper::SetObserver(Observer* observer) {
+ CheckOnValidThread();
+ observer_ = observer;
+ DCHECK(task_queue_manager_);
+ task_queue_manager_->SetObserver(this);
+}
+
+void SchedulerHelper::OnUnregisterTaskQueue(
+ const scoped_refptr<internal::TaskQueueImpl>& queue) {
+ if (observer_)
+ observer_->OnUnregisterTaskQueue(queue);
+}
+
} // namespace scheduler
diff --git a/chromium/components/scheduler/child/scheduler_helper.h b/chromium/components/scheduler/child/scheduler_helper.h
index 5c0c973bc1f..241ae609d16 100644
--- a/chromium/components/scheduler/child/scheduler_helper.h
+++ b/chromium/components/scheduler/child/scheduler_helper.h
@@ -5,8 +5,8 @@
#ifndef COMPONENTS_SCHEDULER_CHILD_SCHEDULER_HELPER_H_
#define COMPONENTS_SCHEDULER_CHILD_SCHEDULER_HELPER_H_
-#include "components/scheduler/child/prioritizing_task_queue_selector.h"
-#include "components/scheduler/child/task_queue_manager.h"
+#include "components/scheduler/base/task_queue_manager.h"
+#include "components/scheduler/base/task_queue_selector.h"
#include "components/scheduler/scheduler_export.h"
namespace base {
@@ -15,21 +15,22 @@ class TickClock;
namespace scheduler {
-class NestableSingleThreadTaskRunner;
+class SchedulerTaskRunnerDelegate;
// Common scheduler functionality for default tasks.
-class SCHEDULER_EXPORT SchedulerHelper {
+class SCHEDULER_EXPORT SchedulerHelper : public TaskQueueManager::Observer {
public:
- // NOTE |total_task_queue_count| must be >= TASK_QUEUE_COUNT.
// Category strings must have application lifetime (statics or
// literals). They may not include " chars.
- SchedulerHelper(
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
- const char* tracing_category,
- const char* disabled_by_default_tracing_category,
- const char* disabled_by_default_verbose_tracing_category,
- size_t total_task_queue_count);
- ~SchedulerHelper();
+ SchedulerHelper(scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner,
+ const char* tracing_category,
+ const char* disabled_by_default_tracing_category,
+ const char* disabled_by_default_verbose_tracing_category);
+ ~SchedulerHelper() override;
+
+ // TaskQueueManager::Observer implementation:
+ void OnUnregisterTaskQueue(
+ const scoped_refptr<internal::TaskQueueImpl>& queue) override;
// Returns the default task runner.
scoped_refptr<TaskQueue> DefaultTaskRunner();
@@ -37,12 +38,12 @@ class SCHEDULER_EXPORT SchedulerHelper {
// Returns the control task runner. Tasks posted to this runner are executed
// with the highest priority. Care must be taken to avoid starvation of other
// task queues.
- scoped_refptr<base::SingleThreadTaskRunner> ControlTaskRunner();
+ scoped_refptr<TaskQueue> ControlTaskRunner();
// Returns the control task after wakeup runner. Tasks posted to this runner
// are executed with the highest priority but do not cause the scheduler to
// wake up. Care must be taken to avoid starvation of other task queues.
- scoped_refptr<base::SingleThreadTaskRunner> ControlAfterWakeUpTaskRunner();
+ scoped_refptr<TaskQueue> ControlAfterWakeUpTaskRunner();
// Adds or removes a task observer from the scheduler. The observer will be
// notified before and after every executed task. These functions can only be
@@ -58,42 +59,31 @@ class SCHEDULER_EXPORT SchedulerHelper {
// Returns true if Shutdown() has been called. Otherwise returns false.
bool IsShutdown() const { return !task_queue_manager_.get(); }
- // Keep SchedulerHelper::TaskQueueIdToString in sync with this enum.
- enum QueueId {
- DEFAULT_TASK_QUEUE,
- CONTROL_TASK_QUEUE,
- CONTROL_TASK_AFTER_WAKEUP_QUEUE,
- // Must be the last entry.
- TASK_QUEUE_COUNT,
- FIRST_QUEUE_ID = DEFAULT_TASK_QUEUE,
- };
-
- static const char* TaskQueueIdToString(QueueId queue_id);
-
void CheckOnValidThread() const {
DCHECK(thread_checker_.CalledOnValidThread());
}
+ // Creates a new TaskQueue with the given |spec|.
+ scoped_refptr<TaskQueue> NewTaskQueue(const TaskQueue::Spec& spec);
+
+ class SCHEDULER_EXPORT Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Called when |queue| is unregistered.
+ virtual void OnUnregisterTaskQueue(
+ const scoped_refptr<TaskQueue>& queue) = 0;
+ };
+
+ // Called once to set the Observer. This function is called on the main
+ // thread. If |observer| is null, then no callbacks will occur.
+ // Note |observer| is expected to outlive the SchedulerHelper.
+ void SetObserver(Observer* observer);
+
// Accessor methods.
base::TimeTicks Now() const;
- scoped_refptr<TaskQueue> TaskRunnerForQueue(size_t queue_index) const;
base::TimeTicks NextPendingDelayedTaskRunTime() const;
- void SetQueueName(size_t queue_index, const char* name);
- bool IsQueueEmpty(size_t queue_index) const;
- TaskQueueManager::QueueState GetQueueState(size_t queue_index) const;
- void SetQueuePriority(size_t queue_index,
- PrioritizingTaskQueueSelector::QueuePriority priority);
- void EnableQueue(size_t queue_index,
- PrioritizingTaskQueueSelector::QueuePriority priority);
- void DisableQueue(size_t queue_index);
- bool IsQueueEnabled(size_t queue_index) const;
- void SetPumpPolicy(size_t queue_index,
- TaskQueueManager::PumpPolicy pump_policy);
- void SetWakeupPolicy(size_t queue_index,
- TaskQueueManager::WakeupPolicy wakeup_policy);
- void PumpQueue(size_t queue_index);
- uint64 GetQuiescenceMonitoredTaskQueueMask() const;
- uint64 GetAndClearTaskWasRunOnQueueBitmap();
+ bool GetAndClearSystemIsQuiescentBit();
// Test helpers.
void SetTimeSourceForTesting(scoped_ptr<base::TickClock> time_source);
@@ -104,17 +94,15 @@ class SCHEDULER_EXPORT SchedulerHelper {
friend class SchedulerHelperTest;
base::ThreadChecker thread_checker_;
- scoped_ptr<PrioritizingTaskQueueSelector> task_queue_selector_;
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner_;
scoped_ptr<TaskQueueManager> task_queue_manager_;
-
- uint64 quiescence_monitored_task_queue_mask_;
-
- scoped_refptr<base::SingleThreadTaskRunner> control_task_runner_;
- scoped_refptr<base::SingleThreadTaskRunner> control_after_wakeup_task_runner_;
+ scoped_refptr<TaskQueue> control_task_runner_;
+ scoped_refptr<TaskQueue> control_after_wakeup_task_runner_;
scoped_refptr<TaskQueue> default_task_runner_;
scoped_ptr<base::TickClock> time_source_;
+ Observer* observer_; // NOT OWNED
const char* tracing_category_;
const char* disabled_by_default_tracing_category_;
diff --git a/chromium/components/scheduler/child/scheduler_helper_unittest.cc b/chromium/components/scheduler/child/scheduler_helper_unittest.cc
index 0e0dd71bb29..5d75bb28790 100644
--- a/chromium/components/scheduler/child/scheduler_helper_unittest.cc
+++ b/chromium/components/scheduler/child/scheduler_helper_unittest.cc
@@ -7,10 +7,9 @@
#include "base/callback.h"
#include "base/test/simple_test_tick_clock.h"
#include "cc/test/ordered_simple_task_runner.h"
-#include "components/scheduler/child/nestable_task_runner_for_test.h"
-#include "components/scheduler/child/scheduler_message_loop_delegate.h"
-#include "components/scheduler/child/task_queue.h"
-#include "components/scheduler/child/test_time_source.h"
+#include "components/scheduler/base/task_queue.h"
+#include "components/scheduler/base/test_time_source.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate_for_test.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -47,14 +46,13 @@ class SchedulerHelperTest : public testing::Test {
SchedulerHelperTest()
: clock_(new base::SimpleTestTickClock()),
mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_.get(), false)),
- nestable_task_runner_(
- NestableTaskRunnerForTest::Create(mock_task_runner_)),
- scheduler_helper_(
- new SchedulerHelper(nestable_task_runner_,
- "test.scheduler",
- TRACE_DISABLED_BY_DEFAULT("test.scheduler"),
- TRACE_DISABLED_BY_DEFAULT("test.scheduler.dbg"),
- SchedulerHelper::TASK_QUEUE_COUNT)),
+ main_task_runner_(
+ SchedulerTaskRunnerDelegateForTest::Create(mock_task_runner_)),
+ scheduler_helper_(new SchedulerHelper(
+ main_task_runner_,
+ "test.scheduler",
+ TRACE_DISABLED_BY_DEFAULT("test.scheduler"),
+ TRACE_DISABLED_BY_DEFAULT("test.scheduler.dbg"))),
default_task_runner_(scheduler_helper_->DefaultTaskRunner()) {
clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
scheduler_helper_->SetTimeSourceForTesting(
@@ -84,17 +82,11 @@ class SchedulerHelperTest : public testing::Test {
}
}
- static void CheckAllTaskQueueIdToString() {
- CallForEachEnumValue<SchedulerHelper::QueueId>(
- SchedulerHelper::FIRST_QUEUE_ID, SchedulerHelper::TASK_QUEUE_COUNT,
- &SchedulerHelper::TaskQueueIdToString);
- }
-
protected:
scoped_ptr<base::SimpleTestTickClock> clock_;
scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
- scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
+ scoped_refptr<SchedulerTaskRunnerDelegateForTest> main_task_runner_;
scoped_ptr<SchedulerHelper> scheduler_helper_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
@@ -136,8 +128,82 @@ TEST_F(SchedulerHelperTest, IsShutdown) {
EXPECT_TRUE(scheduler_helper_->IsShutdown());
}
-TEST_F(SchedulerHelperTest, TaskQueueIdToString) {
- CheckAllTaskQueueIdToString();
+TEST_F(SchedulerHelperTest, DefaultTaskRunnerRegistration) {
+ EXPECT_EQ(main_task_runner_->default_task_runner(),
+ scheduler_helper_->DefaultTaskRunner());
+ scheduler_helper_->Shutdown();
+ EXPECT_EQ(nullptr, main_task_runner_->default_task_runner());
+}
+
+namespace {
+class MockTaskObserver : public base::MessageLoop::TaskObserver {
+ public:
+ MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task));
+ MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task));
+};
+
+void NopTask() {}
+} // namespace
+
+TEST_F(SchedulerHelperTest, ObserversNotifiedFor_DefaultTaskRunner) {
+ MockTaskObserver observer;
+ scheduler_helper_->AddTaskObserver(&observer);
+
+ scheduler_helper_->DefaultTaskRunner()->PostTask(FROM_HERE,
+ base::Bind(&NopTask));
+
+ EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
+ EXPECT_CALL(observer, DidProcessTask(_)).Times(1);
+ RunUntilIdle();
+}
+
+TEST_F(SchedulerHelperTest, ObserversNotNotifiedFor_ControlTaskRunner) {
+ MockTaskObserver observer;
+ scheduler_helper_->AddTaskObserver(&observer);
+
+ scheduler_helper_->ControlTaskRunner()->PostTask(FROM_HERE,
+ base::Bind(&NopTask));
+
+ EXPECT_CALL(observer, WillProcessTask(_)).Times(0);
+ EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
+ RunUntilIdle();
+}
+
+TEST_F(SchedulerHelperTest,
+ ObserversNotNotifiedFor_ControlAfterWakeUpTaskRunner) {
+ MockTaskObserver observer;
+ scheduler_helper_->AddTaskObserver(&observer);
+
+ scheduler_helper_->ControlAfterWakeUpTaskRunner()->PostTask(
+ FROM_HERE, base::Bind(&NopTask));
+
+ EXPECT_CALL(observer, WillProcessTask(_)).Times(0);
+ EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
+ scheduler_helper_->ControlAfterWakeUpTaskRunner()->PumpQueue();
+ RunUntilIdle();
+}
+
+namespace {
+
+class MockObserver : public SchedulerHelper::Observer {
+ public:
+ MOCK_METHOD1(OnUnregisterTaskQueue,
+ void(const scoped_refptr<TaskQueue>& queue));
+};
+
+} // namespace
+
+TEST_F(SchedulerHelperTest, OnUnregisterTaskQueue) {
+ MockObserver observer;
+ scheduler_helper_->SetObserver(&observer);
+
+ scoped_refptr<TaskQueue> task_queue =
+ scheduler_helper_->NewTaskQueue(TaskQueue::Spec("test_queue"));
+
+ EXPECT_CALL(observer, OnUnregisterTaskQueue(_)).Times(1);
+ task_queue->UnregisterTaskQueue();
+
+ scheduler_helper_->SetObserver(nullptr);
}
} // namespace scheduler
diff --git a/chromium/components/scheduler/child/scheduler_message_loop_delegate.cc b/chromium/components/scheduler/child/scheduler_message_loop_delegate.cc
deleted file mode 100644
index ba0d6b404e3..00000000000
--- a/chromium/components/scheduler/child/scheduler_message_loop_delegate.cc
+++ /dev/null
@@ -1,56 +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/scheduler/child/scheduler_message_loop_delegate.h"
-
-namespace scheduler {
-
-// static
-scoped_refptr<SchedulerMessageLoopDelegate>
-SchedulerMessageLoopDelegate::Create(base::MessageLoop* message_loop) {
- return make_scoped_refptr(new SchedulerMessageLoopDelegate(message_loop));
-}
-
-SchedulerMessageLoopDelegate::SchedulerMessageLoopDelegate(
- base::MessageLoop* message_loop)
- : message_loop_(message_loop) {
-}
-
-SchedulerMessageLoopDelegate::~SchedulerMessageLoopDelegate() {
-}
-
-bool SchedulerMessageLoopDelegate::PostDelayedTask(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- return message_loop_->task_runner()->PostDelayedTask(from_here, task, delay);
-}
-
-bool SchedulerMessageLoopDelegate::PostNonNestableDelayedTask(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- return message_loop_->task_runner()->PostNonNestableDelayedTask(from_here,
- task, delay);
-}
-
-bool SchedulerMessageLoopDelegate::RunsTasksOnCurrentThread() const {
- return message_loop_->task_runner()->RunsTasksOnCurrentThread();
-}
-
-bool SchedulerMessageLoopDelegate::IsNested() const {
- return message_loop_->IsNested();
-}
-
-void SchedulerMessageLoopDelegate::AddTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- return message_loop_->AddTaskObserver(task_observer);
-}
-
-void SchedulerMessageLoopDelegate::RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- return message_loop_->RemoveTaskObserver(task_observer);
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/child/scheduler_task_runner_delegate.h b/chromium/components/scheduler/child/scheduler_task_runner_delegate.h
new file mode 100644
index 00000000000..dd0fc146deb
--- /dev/null
+++ b/chromium/components/scheduler/child/scheduler_task_runner_delegate.h
@@ -0,0 +1,37 @@
+// 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_SCHEDULER_CHILD_SCHEDULER_TASK_RUNNER_DELEGATE_H_
+#define COMPONENTS_SCHEDULER_CHILD_SCHEDULER_TASK_RUNNER_DELEGATE_H_
+
+#include "base/message_loop/message_loop.h"
+#include "components/scheduler/base/nestable_single_thread_task_runner.h"
+#include "components/scheduler/scheduler_export.h"
+
+namespace scheduler {
+
+class SCHEDULER_EXPORT SchedulerTaskRunnerDelegate
+ : public NestableSingleThreadTaskRunner {
+ public:
+ SchedulerTaskRunnerDelegate() {}
+
+ // If the underlying task runner supports the concept of a default task
+ // runner, the delegate should implement this function to redirect that task
+ // runner to the scheduler.
+ virtual void SetDefaultTaskRunner(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) = 0;
+
+ // Similarly this method can be used to restore the original task runner when
+ // the scheduler no longer wants to intercept tasks.
+ virtual void RestoreDefaultTaskRunner() = 0;
+
+ protected:
+ ~SchedulerTaskRunnerDelegate() override {}
+
+ DISALLOW_COPY_AND_ASSIGN(SchedulerTaskRunnerDelegate);
+};
+
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_CHILD_SCHEDULER_TASK_RUNNER_DELEGATE_H_
diff --git a/chromium/components/scheduler/child/scheduler_task_runner_delegate_for_test.cc b/chromium/components/scheduler/child/scheduler_task_runner_delegate_for_test.cc
new file mode 100644
index 00000000000..4405d6d8011
--- /dev/null
+++ b/chromium/components/scheduler/child/scheduler_task_runner_delegate_for_test.cc
@@ -0,0 +1,58 @@
+// 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/scheduler/child/scheduler_task_runner_delegate_for_test.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "components/scheduler/base/nestable_task_runner_for_test.h"
+
+namespace scheduler {
+
+// static
+scoped_refptr<SchedulerTaskRunnerDelegateForTest>
+SchedulerTaskRunnerDelegateForTest::Create(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ return make_scoped_refptr(
+ new SchedulerTaskRunnerDelegateForTest(task_runner));
+}
+
+SchedulerTaskRunnerDelegateForTest::SchedulerTaskRunnerDelegateForTest(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : task_runner_(NestableTaskRunnerForTest::Create(task_runner)) {}
+
+SchedulerTaskRunnerDelegateForTest::~SchedulerTaskRunnerDelegateForTest() {}
+
+void SchedulerTaskRunnerDelegateForTest::SetDefaultTaskRunner(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ default_task_runner_ = task_runner.Pass();
+}
+
+void SchedulerTaskRunnerDelegateForTest::RestoreDefaultTaskRunner() {
+ default_task_runner_ = nullptr;
+}
+
+bool SchedulerTaskRunnerDelegateForTest::PostDelayedTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) {
+ return task_runner_->PostDelayedTask(from_here, task, delay);
+}
+
+bool SchedulerTaskRunnerDelegateForTest::PostNonNestableDelayedTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) {
+ return task_runner_->PostNonNestableDelayedTask(from_here, task, delay);
+}
+
+bool SchedulerTaskRunnerDelegateForTest::RunsTasksOnCurrentThread() const {
+ return task_runner_->RunsTasksOnCurrentThread();
+}
+
+bool SchedulerTaskRunnerDelegateForTest::IsNested() const {
+ return task_runner_->IsNested();
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/child/scheduler_task_runner_delegate_for_test.h b/chromium/components/scheduler/child/scheduler_task_runner_delegate_for_test.h
new file mode 100644
index 00000000000..27c6309d850
--- /dev/null
+++ b/chromium/components/scheduler/child/scheduler_task_runner_delegate_for_test.h
@@ -0,0 +1,52 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_SCHEDULER_TASK_RUNNER_DELEGATE_FOR_TEST_H_
+#define CONTENT_RENDERER_SCHEDULER_TASK_RUNNER_DELEGATE_FOR_TEST_H_
+
+#include "components/scheduler/child/scheduler_task_runner_delegate.h"
+
+namespace scheduler {
+
+class NestableTaskRunnerForTest;
+
+class SchedulerTaskRunnerDelegateForTest : public SchedulerTaskRunnerDelegate {
+ public:
+ static scoped_refptr<SchedulerTaskRunnerDelegateForTest> Create(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+ // SchedulerTaskRunnerDelegate implementation
+ void SetDefaultTaskRunner(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
+ void RestoreDefaultTaskRunner() override;
+ bool PostDelayedTask(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) override;
+ bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) override;
+ bool RunsTasksOnCurrentThread() const override;
+ bool IsNested() const override;
+
+ base::SingleThreadTaskRunner* default_task_runner() const {
+ return default_task_runner_.get();
+ }
+
+ protected:
+ ~SchedulerTaskRunnerDelegateForTest() override;
+
+ private:
+ explicit SchedulerTaskRunnerDelegateForTest(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+ scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
+
+ scoped_refptr<NestableTaskRunnerForTest> task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(SchedulerTaskRunnerDelegateForTest);
+};
+
+} // namespace scheduler
+
+#endif // CONTENT_RENDERER_SCHEDULER_SCHEDULER_TASK_RUNNER_DELEGATE_FOR_TEST_H_
diff --git a/chromium/components/scheduler/child/scheduler_task_runner_delegate_impl.cc b/chromium/components/scheduler/child/scheduler_task_runner_delegate_impl.cc
new file mode 100644
index 00000000000..0c34554b106
--- /dev/null
+++ b/chromium/components/scheduler/child/scheduler_task_runner_delegate_impl.cc
@@ -0,0 +1,57 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/scheduler/child/scheduler_task_runner_delegate_impl.h"
+
+namespace scheduler {
+
+// static
+scoped_refptr<SchedulerTaskRunnerDelegateImpl>
+SchedulerTaskRunnerDelegateImpl::Create(base::MessageLoop* message_loop) {
+ return make_scoped_refptr(new SchedulerTaskRunnerDelegateImpl(message_loop));
+}
+
+SchedulerTaskRunnerDelegateImpl::SchedulerTaskRunnerDelegateImpl(
+ base::MessageLoop* message_loop)
+ : message_loop_(message_loop),
+ message_loop_task_runner_(message_loop->task_runner()) {}
+
+SchedulerTaskRunnerDelegateImpl::~SchedulerTaskRunnerDelegateImpl() {
+ RestoreDefaultTaskRunner();
+}
+
+void SchedulerTaskRunnerDelegateImpl::SetDefaultTaskRunner(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ message_loop_->SetTaskRunner(task_runner);
+}
+
+void SchedulerTaskRunnerDelegateImpl::RestoreDefaultTaskRunner() {
+ if (base::MessageLoop::current() == message_loop_)
+ message_loop_->SetTaskRunner(message_loop_task_runner_);
+}
+
+bool SchedulerTaskRunnerDelegateImpl::PostDelayedTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) {
+ return message_loop_task_runner_->PostDelayedTask(from_here, task, delay);
+}
+
+bool SchedulerTaskRunnerDelegateImpl::PostNonNestableDelayedTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) {
+ return message_loop_task_runner_->PostNonNestableDelayedTask(from_here, task,
+ delay);
+}
+
+bool SchedulerTaskRunnerDelegateImpl::RunsTasksOnCurrentThread() const {
+ return message_loop_task_runner_->RunsTasksOnCurrentThread();
+}
+
+bool SchedulerTaskRunnerDelegateImpl::IsNested() const {
+ return message_loop_->IsNested();
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/child/scheduler_message_loop_delegate.h b/chromium/components/scheduler/child/scheduler_task_runner_delegate_impl.h
index 164ab31768a..2f18b992c68 100644
--- a/chromium/components/scheduler/child/scheduler_message_loop_delegate.h
+++ b/chromium/components/scheduler/child/scheduler_task_runner_delegate_impl.h
@@ -2,23 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_SCHEDULER_CHILD_SCHEDULER_MESSAGE_LOOP_DELEGATE_H_
-#define COMPONENTS_SCHEDULER_CHILD_SCHEDULER_MESSAGE_LOOP_DELEGATE_H_
+#ifndef COMPONENTS_SCHEDULER_CHILD_SCHEDULER_TASK_RUNNER_DELEGATE_IMPL_H_
+#define COMPONENTS_SCHEDULER_CHILD_SCHEDULER_TASK_RUNNER_DELEGATE_IMPL_H_
#include "base/message_loop/message_loop.h"
-#include "components/scheduler/child/nestable_single_thread_task_runner.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate.h"
#include "components/scheduler/scheduler_export.h"
namespace scheduler {
-class SCHEDULER_EXPORT SchedulerMessageLoopDelegate
- : public NestableSingleThreadTaskRunner {
+class SCHEDULER_EXPORT SchedulerTaskRunnerDelegateImpl
+ : public SchedulerTaskRunnerDelegate {
public:
// |message_loop| is not owned and must outlive the lifetime of this object.
- static scoped_refptr<SchedulerMessageLoopDelegate> Create(
+ static scoped_refptr<SchedulerTaskRunnerDelegateImpl> Create(
base::MessageLoop* message_loop);
- // NestableSingleThreadTaskRunner implementation
+ // SchedulerTaskRunnerDelegate implementation
+ void SetDefaultTaskRunner(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
+ void RestoreDefaultTaskRunner() override;
bool PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) override;
@@ -27,22 +30,20 @@ class SCHEDULER_EXPORT SchedulerMessageLoopDelegate
base::TimeDelta delay) override;
bool RunsTasksOnCurrentThread() const override;
bool IsNested() const override;
- void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
- void RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) override;
protected:
- ~SchedulerMessageLoopDelegate() override;
+ ~SchedulerTaskRunnerDelegateImpl() override;
private:
- SchedulerMessageLoopDelegate(base::MessageLoop* message_loop);
+ explicit SchedulerTaskRunnerDelegateImpl(base::MessageLoop* message_loop);
// Not owned.
base::MessageLoop* message_loop_;
+ scoped_refptr<SingleThreadTaskRunner> message_loop_task_runner_;
- DISALLOW_COPY_AND_ASSIGN(SchedulerMessageLoopDelegate);
+ DISALLOW_COPY_AND_ASSIGN(SchedulerTaskRunnerDelegateImpl);
};
} // namespace scheduler
-#endif // COMPONENTS_SCHEDULER_CHILD_SCHEDULER_MESSAGE_LOOP_DELEGATE_H_
+#endif // COMPONENTS_SCHEDULER_CHILD_SCHEDULER_TASK_RUNNER_DELEGATE_IMPL_H_
diff --git a/chromium/components/scheduler/child/scheduler_task_runner_delegate_impl_unittest.cc b/chromium/components/scheduler/child/scheduler_task_runner_delegate_impl_unittest.cc
new file mode 100644
index 00000000000..7e55a1242b3
--- /dev/null
+++ b/chromium/components/scheduler/child/scheduler_task_runner_delegate_impl_unittest.cc
@@ -0,0 +1,28 @@
+// 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/scheduler/child/scheduler_task_runner_delegate_impl.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/test/test_simple_task_runner.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace scheduler {
+
+TEST(SchedulerTaskRunnerDelegateImplTest, TestTaskRunnerOverriding) {
+ base::MessageLoop loop;
+ scoped_refptr<base::SingleThreadTaskRunner> original_runner(
+ loop.task_runner());
+ scoped_refptr<base::SingleThreadTaskRunner> custom_runner(
+ new base::TestSimpleTaskRunner());
+ {
+ scoped_refptr<SchedulerTaskRunnerDelegateImpl> delegate(
+ SchedulerTaskRunnerDelegateImpl::Create(&loop));
+ delegate->SetDefaultTaskRunner(custom_runner);
+ DCHECK_EQ(custom_runner, loop.task_runner());
+ }
+ DCHECK_EQ(original_runner, loop.task_runner());
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/child/task_queue.h b/chromium/components/scheduler/child/task_queue.h
deleted file mode 100644
index a574c617ce0..00000000000
--- a/chromium/components/scheduler/child/task_queue.h
+++ /dev/null
@@ -1,31 +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_SCHEDULER_CHILD_TASK_QUEUE_H_
-#define COMPONENTS_SCHEDULER_CHILD_TASK_QUEUE_H_
-
-#include "base/single_thread_task_runner.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace scheduler {
-
-class SCHEDULER_EXPORT TaskQueue : public base::SingleThreadTaskRunner {
- public:
- TaskQueue() {}
-
- // Post a delayed task at an absolute desired run time instead of a time
- // delta from the current time.
- virtual bool PostDelayedTaskAt(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeTicks desired_run_time) = 0;
-
- protected:
- ~TaskQueue() override {}
-
- DISALLOW_COPY_AND_ASSIGN(TaskQueue);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_CHILD_TASK_QUEUE_H_
diff --git a/chromium/components/scheduler/child/task_queue_manager.cc b/chromium/components/scheduler/child/task_queue_manager.cc
deleted file mode 100644
index 606fe7f35b0..00000000000
--- a/chromium/components/scheduler/child/task_queue_manager.cc
+++ /dev/null
@@ -1,862 +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/scheduler/child/task_queue_manager.h"
-
-#include <queue>
-#include <set>
-
-#include "base/bind.h"
-#include "base/time/default_tick_clock.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "components/scheduler/child/nestable_single_thread_task_runner.h"
-#include "components/scheduler/child/task_queue.h"
-#include "components/scheduler/child/task_queue_selector.h"
-
-namespace {
-const int64_t kMaxTimeTicks = std::numeric_limits<int64>::max();
-}
-
-namespace scheduler {
-namespace internal {
-
-// Now() is somewhat expensive so it makes sense not to call Now() unless we
-// really need to.
-class LazyNow {
- public:
- explicit LazyNow(base::TimeTicks now)
- : task_queue_manager_(nullptr), now_(now) {
- DCHECK(!now.is_null());
- }
-
- explicit LazyNow(TaskQueueManager* task_queue_manager)
- : task_queue_manager_(task_queue_manager) {}
-
- base::TimeTicks Now() {
- if (now_.is_null())
- now_ = task_queue_manager_->Now();
- return now_;
- }
-
- private:
- TaskQueueManager* task_queue_manager_; // NOT OWNED
- base::TimeTicks now_;
-};
-
-class TaskQueueImpl : public TaskQueue {
- public:
- TaskQueueImpl(TaskQueueManager* task_queue_manager,
- const char* disabled_by_default_tracing_category,
- const char* disabled_by_default_verbose_tracing_category);
-
- // TaskQueue :implementation.
- bool RunsTasksOnCurrentThread() const override;
- bool PostDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) override {
- return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL);
- }
-
- bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) override {
- return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE);
- }
- bool PostDelayedTaskAt(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeTicks desired_run_time) override;
-
- TaskQueueManager::QueueState GetQueueState() const;
-
- void SetPumpPolicy(TaskQueueManager::PumpPolicy pump_policy);
- void PumpQueue();
-
- bool NextPendingDelayedTaskRunTime(
- base::TimeTicks* next_pending_delayed_task);
-
- bool UpdateWorkQueue(LazyNow* lazy_now,
- bool should_trigger_wakeup,
- const base::PendingTask* previous_task);
- base::PendingTask TakeTaskFromWorkQueue();
-
- void WillDeleteTaskQueueManager();
-
- base::TaskQueue& work_queue() { return work_queue_; }
-
- void set_name(const char* name) { name_ = name; }
-
- TaskQueueManager::WakeupPolicy wakeup_policy() const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- return wakeup_policy_;
- }
-
- void set_wakeup_policy(TaskQueueManager::WakeupPolicy wakeup_policy) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- wakeup_policy_ = wakeup_policy;
- }
-
- void AsValueInto(base::trace_event::TracedValue* state) const;
-
- private:
- enum class TaskType {
- NORMAL,
- NON_NESTABLE,
- };
-
- ~TaskQueueImpl() override;
-
- bool PostDelayedTaskImpl(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay,
- TaskType task_type);
- bool PostDelayedTaskLocked(LazyNow* lazy_now,
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeTicks desired_run_time,
- TaskType task_type);
-
- // Delayed task posted to the underlying run loop, which locks |lock_| and
- // calls MoveReadyDelayedTasksToIncomingQueueLocked to process dealyed tasks
- // that need to be run now.
- void MoveReadyDelayedTasksToIncomingQueue();
-
- // Enqueues any delayed tasks which should be run now on the incoming_queue_
- // and calls ScheduleDelayedWorkLocked to ensure future tasks are scheduled.
- // Must be called with |lock_| locked.
- void MoveReadyDelayedTasksToIncomingQueueLocked(LazyNow* lazy_now);
-
- // Posts MoveReadyDelayedTasksToIncomingQueue if there isn't already a task
- // posted on the underlying runloop for the next task's scheduled run time.
- void ScheduleDelayedWorkLocked(LazyNow* lazy_now);
-
- void PumpQueueLocked();
- bool TaskIsOlderThanQueuedTasks(const base::PendingTask* task);
- bool ShouldAutoPumpQueueLocked(bool should_trigger_wakeup,
- const base::PendingTask* previous_task);
-
- // Push the task onto the |incoming_queue_| and allocate a sequence number
- // for it.
- void EnqueueTaskLocked(const base::PendingTask& pending_task);
-
- void TraceQueueSize(bool is_locked) const;
- static void QueueAsValueInto(const base::TaskQueue& queue,
- base::trace_event::TracedValue* state);
- static void QueueAsValueInto(const base::DelayedTaskQueue& queue,
- base::trace_event::TracedValue* state);
- static void TaskAsValueInto(const base::PendingTask& task,
- base::trace_event::TracedValue* state);
-
- // This lock protects all members except the work queue, the
- // main_thread_checker_ and wakeup_policy_.
- mutable base::Lock lock_;
- base::PlatformThreadId thread_id_;
- TaskQueueManager* task_queue_manager_;
- base::TaskQueue incoming_queue_;
- TaskQueueManager::PumpPolicy pump_policy_;
- const char* name_;
- const char* disabled_by_default_tracing_category_;
- const char* disabled_by_default_verbose_tracing_category_;
-
- // Queue-local task sequence number for maintaining the order of delayed
- // tasks which are posted for the exact same time. Note that this will be
- // replaced by the global sequence number when the delay has elapsed.
- int delayed_task_sequence_number_;
- base::DelayedTaskQueue delayed_task_queue_;
- std::set<base::TimeTicks> in_flight_kick_delayed_tasks_;
-
- base::ThreadChecker main_thread_checker_;
- base::TaskQueue work_queue_;
- TaskQueueManager::WakeupPolicy wakeup_policy_;
-
- DISALLOW_COPY_AND_ASSIGN(TaskQueueImpl);
-};
-
-TaskQueueImpl::TaskQueueImpl(
- TaskQueueManager* task_queue_manager,
- const char* disabled_by_default_tracing_category,
- const char* disabled_by_default_verbose_tracing_category)
- : thread_id_(base::PlatformThread::CurrentId()),
- task_queue_manager_(task_queue_manager),
- pump_policy_(TaskQueueManager::PumpPolicy::AUTO),
- name_(nullptr),
- disabled_by_default_tracing_category_(
- disabled_by_default_tracing_category),
- disabled_by_default_verbose_tracing_category_(
- disabled_by_default_verbose_tracing_category),
- delayed_task_sequence_number_(0),
- wakeup_policy_(TaskQueueManager::WakeupPolicy::CAN_WAKE_OTHER_QUEUES) {}
-
-TaskQueueImpl::~TaskQueueImpl() {}
-
-void TaskQueueImpl::WillDeleteTaskQueueManager() {
- base::AutoLock lock(lock_);
- task_queue_manager_ = nullptr;
- delayed_task_queue_ = base::DelayedTaskQueue();
- incoming_queue_ = base::TaskQueue();
- work_queue_ = base::TaskQueue();
-}
-
-bool TaskQueueImpl::RunsTasksOnCurrentThread() const {
- base::AutoLock lock(lock_);
- return base::PlatformThread::CurrentId() == thread_id_;
-}
-
-bool TaskQueueImpl::PostDelayedTaskAt(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeTicks desired_run_time) {
- base::AutoLock lock(lock_);
- if (!task_queue_manager_)
- return false;
- LazyNow lazy_now(task_queue_manager_);
- return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time,
- TaskType::NORMAL);
-}
-
-bool TaskQueueImpl::PostDelayedTaskImpl(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay,
- TaskType task_type) {
- base::AutoLock lock(lock_);
- if (!task_queue_manager_)
- return false;
- LazyNow lazy_now(task_queue_manager_);
- base::TimeTicks desired_run_time;
- if (delay > base::TimeDelta())
- desired_run_time = lazy_now.Now() + delay;
- return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time,
- task_type);
-}
-
-bool TaskQueueImpl::PostDelayedTaskLocked(
- LazyNow* lazy_now,
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeTicks desired_run_time,
- TaskType task_type) {
- lock_.AssertAcquired();
- DCHECK(task_queue_manager_);
-
- base::PendingTask pending_task(from_here, task, base::TimeTicks(),
- task_type != TaskType::NON_NESTABLE);
- task_queue_manager_->DidQueueTask(pending_task);
-
- if (!desired_run_time.is_null()) {
- pending_task.delayed_run_time = std::max(lazy_now->Now(), desired_run_time);
- pending_task.sequence_num = delayed_task_sequence_number_++;
- delayed_task_queue_.push(pending_task);
- TraceQueueSize(true);
- // If we changed the topmost task, then it is time to reschedule.
- if (delayed_task_queue_.top().task.Equals(pending_task.task))
- ScheduleDelayedWorkLocked(lazy_now);
- return true;
- }
- EnqueueTaskLocked(pending_task);
- return true;
-}
-
-void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue() {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- base::AutoLock lock(lock_);
- if (!task_queue_manager_)
- return;
-
- LazyNow lazy_now(task_queue_manager_);
- MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now);
-}
-
-void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueueLocked(
- LazyNow* lazy_now) {
- lock_.AssertAcquired();
- // Enqueue all delayed tasks that should be running now.
- while (!delayed_task_queue_.empty() &&
- delayed_task_queue_.top().delayed_run_time <= lazy_now->Now()) {
- in_flight_kick_delayed_tasks_.erase(
- delayed_task_queue_.top().delayed_run_time);
- EnqueueTaskLocked(delayed_task_queue_.top());
- delayed_task_queue_.pop();
- }
- TraceQueueSize(true);
- ScheduleDelayedWorkLocked(lazy_now);
-}
-
-void TaskQueueImpl::ScheduleDelayedWorkLocked(LazyNow* lazy_now) {
- lock_.AssertAcquired();
- // Any remaining tasks are in the future, so queue a task to kick them.
- if (!delayed_task_queue_.empty()) {
- base::TimeTicks next_run_time = delayed_task_queue_.top().delayed_run_time;
- DCHECK_GE(next_run_time, lazy_now->Now());
- // Make sure we don't have more than one
- // MoveReadyDelayedTasksToIncomingQueue posted for a particular scheduled
- // run time (note it's fine to have multiple ones in flight for distinct
- // run times).
- if (in_flight_kick_delayed_tasks_.find(next_run_time) ==
- in_flight_kick_delayed_tasks_.end()) {
- in_flight_kick_delayed_tasks_.insert(next_run_time);
- base::TimeDelta delay = next_run_time - lazy_now->Now();
- task_queue_manager_->PostDelayedTask(
- FROM_HERE,
- Bind(&TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue, this),
- delay);
- }
- }
-}
-
-TaskQueueManager::QueueState TaskQueueImpl::GetQueueState() const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- if (!work_queue_.empty())
- return TaskQueueManager::QueueState::HAS_WORK;
-
- {
- base::AutoLock lock(lock_);
- if (incoming_queue_.empty()) {
- return TaskQueueManager::QueueState::EMPTY;
- } else {
- return TaskQueueManager::QueueState::NEEDS_PUMPING;
- }
- }
-}
-
-bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const base::PendingTask* task) {
- lock_.AssertAcquired();
- // A null task is passed when UpdateQueue is called before any task is run.
- // In this case we don't want to pump an after_wakeup queue, so return true
- // here.
- if (!task)
- return true;
-
- // Return false if there are no task in the incoming queue.
- if (incoming_queue_.empty())
- return false;
-
- base::PendingTask oldest_queued_task = incoming_queue_.front();
- DCHECK(oldest_queued_task.delayed_run_time.is_null());
- DCHECK(task->delayed_run_time.is_null());
-
- // Note: the comparison is correct due to the fact that the PendingTask
- // operator inverts its comparison operation in order to work well in a heap
- // based priority queue.
- return oldest_queued_task < *task;
-}
-
-bool TaskQueueImpl::ShouldAutoPumpQueueLocked(
- bool should_trigger_wakeup,
- const base::PendingTask* previous_task) {
- lock_.AssertAcquired();
- if (pump_policy_ == TaskQueueManager::PumpPolicy::MANUAL)
- return false;
- if (pump_policy_ == TaskQueueManager::PumpPolicy::AFTER_WAKEUP &&
- (!should_trigger_wakeup || TaskIsOlderThanQueuedTasks(previous_task)))
- return false;
- if (incoming_queue_.empty())
- return false;
- return true;
-}
-
-bool TaskQueueImpl::NextPendingDelayedTaskRunTime(
- base::TimeTicks* next_pending_delayed_task) {
- base::AutoLock lock(lock_);
- if (delayed_task_queue_.empty())
- return false;
- *next_pending_delayed_task = delayed_task_queue_.top().delayed_run_time;
- return true;
-}
-
-bool TaskQueueImpl::UpdateWorkQueue(LazyNow* lazy_now,
- bool should_trigger_wakeup,
- const base::PendingTask* previous_task) {
- if (!work_queue_.empty())
- return true;
-
- {
- base::AutoLock lock(lock_);
- if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task))
- return false;
- MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now);
- work_queue_.Swap(&incoming_queue_);
- TraceQueueSize(true);
- return true;
- }
-}
-
-base::PendingTask TaskQueueImpl::TakeTaskFromWorkQueue() {
- base::PendingTask pending_task = work_queue_.front();
- work_queue_.pop();
- TraceQueueSize(false);
- return pending_task;
-}
-
-void TaskQueueImpl::TraceQueueSize(bool is_locked) const {
- bool is_tracing;
- TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_,
- &is_tracing);
- if (!is_tracing || !name_)
- return;
- if (!is_locked)
- lock_.Acquire();
- else
- lock_.AssertAcquired();
- TRACE_COUNTER1(
- disabled_by_default_tracing_category_, name_,
- incoming_queue_.size() + work_queue_.size() + delayed_task_queue_.size());
- if (!is_locked)
- lock_.Release();
-}
-
-void TaskQueueImpl::EnqueueTaskLocked(const base::PendingTask& pending_task) {
- lock_.AssertAcquired();
- if (!task_queue_manager_)
- return;
- if (pump_policy_ == TaskQueueManager::PumpPolicy::AUTO &&
- incoming_queue_.empty())
- task_queue_manager_->MaybePostDoWorkOnMainRunner();
- incoming_queue_.push(pending_task);
- incoming_queue_.back().sequence_num =
- task_queue_manager_->GetNextSequenceNumber();
-
- if (!pending_task.delayed_run_time.is_null()) {
- // Clear the delayed run time because we've already applied the delay
- // before getting here.
- incoming_queue_.back().delayed_run_time = base::TimeTicks();
- }
- TraceQueueSize(true);
-}
-
-void TaskQueueImpl::SetPumpPolicy(TaskQueueManager::PumpPolicy pump_policy) {
- base::AutoLock lock(lock_);
- if (pump_policy == TaskQueueManager::PumpPolicy::AUTO &&
- pump_policy_ != TaskQueueManager::PumpPolicy::AUTO) {
- PumpQueueLocked();
- }
- pump_policy_ = pump_policy;
-}
-
-void TaskQueueImpl::PumpQueueLocked() {
- lock_.AssertAcquired();
- if (task_queue_manager_) {
- LazyNow lazy_now(task_queue_manager_);
- MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now);
- }
- while (!incoming_queue_.empty()) {
- work_queue_.push(incoming_queue_.front());
- incoming_queue_.pop();
- }
- if (!work_queue_.empty())
- task_queue_manager_->MaybePostDoWorkOnMainRunner();
-}
-
-void TaskQueueImpl::PumpQueue() {
- base::AutoLock lock(lock_);
- PumpQueueLocked();
-}
-
-void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
- base::AutoLock lock(lock_);
- state->BeginDictionary();
- if (name_)
- state->SetString("name", name_);
- state->SetString("pump_policy",
- TaskQueueManager::PumpPolicyToString(pump_policy_));
- state->SetString("wakeup_policy",
- TaskQueueManager::WakeupPolicyToString(wakeup_policy_));
- bool verbose_tracing_enabled = false;
- TRACE_EVENT_CATEGORY_GROUP_ENABLED(
- disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled);
- state->SetInteger("incoming_queue_size", incoming_queue_.size());
- state->SetInteger("work_queue_size", work_queue_.size());
- state->SetInteger("delayed_task_queue_size", delayed_task_queue_.size());
- if (verbose_tracing_enabled) {
- state->BeginArray("incoming_queue");
- QueueAsValueInto(incoming_queue_, state);
- state->EndArray();
- state->BeginArray("work_queue");
- QueueAsValueInto(work_queue_, state);
- state->EndArray();
- state->BeginArray("delayed_task_queue");
- QueueAsValueInto(delayed_task_queue_, state);
- state->EndArray();
- }
- state->EndDictionary();
-}
-
-// static
-void TaskQueueImpl::QueueAsValueInto(const base::TaskQueue& queue,
- base::trace_event::TracedValue* state) {
- base::TaskQueue queue_copy(queue);
- while (!queue_copy.empty()) {
- TaskAsValueInto(queue_copy.front(), state);
- queue_copy.pop();
- }
-}
-
-// static
-void TaskQueueImpl::QueueAsValueInto(const base::DelayedTaskQueue& queue,
- base::trace_event::TracedValue* state) {
- base::DelayedTaskQueue queue_copy(queue);
- while (!queue_copy.empty()) {
- TaskAsValueInto(queue_copy.top(), state);
- queue_copy.pop();
- }
-}
-
-// static
-void TaskQueueImpl::TaskAsValueInto(const base::PendingTask& task,
- base::trace_event::TracedValue* state) {
- state->BeginDictionary();
- state->SetString("posted_from", task.posted_from.ToString());
- state->SetInteger("sequence_num", task.sequence_num);
- state->SetBoolean("nestable", task.nestable);
- state->SetBoolean("is_high_res", task.is_high_res);
- state->SetDouble(
- "delayed_run_time",
- (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L);
- state->EndDictionary();
-}
-
-} // namespace internal
-
-TaskQueueManager::TaskQueueManager(
- size_t task_queue_count,
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
- TaskQueueSelector* selector,
- const char* disabled_by_default_tracing_category,
- const char* disabled_by_default_verbose_tracing_category)
- : main_task_runner_(main_task_runner),
- selector_(selector),
- task_was_run_bitmap_(0),
- pending_dowork_count_(0),
- work_batch_size_(1),
- time_source_(new base::DefaultTickClock),
- disabled_by_default_tracing_category_(
- disabled_by_default_tracing_category),
- deletion_sentinel_(new DeletionSentinel()),
- weak_factory_(this) {
- DCHECK(main_task_runner->RunsTasksOnCurrentThread());
- DCHECK_LE(task_queue_count, sizeof(task_was_run_bitmap_) * CHAR_BIT)
- << "You need a bigger int for task_was_run_bitmap_";
- TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category,
- "TaskQueueManager", this);
-
- for (size_t i = 0; i < task_queue_count; i++) {
- scoped_refptr<internal::TaskQueueImpl> queue(
- make_scoped_refptr(new internal::TaskQueueImpl(
- this, disabled_by_default_tracing_category,
- disabled_by_default_verbose_tracing_category)));
- queues_.push_back(queue);
- }
-
- std::vector<const base::TaskQueue*> work_queues;
- for (const auto& queue : queues_)
- work_queues.push_back(&queue->work_queue());
- selector_->RegisterWorkQueues(work_queues);
- selector_->SetTaskQueueSelectorObserver(this);
-
- do_work_from_main_thread_closure_ =
- base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), true);
- do_work_from_other_thread_closure_ =
- base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), false);
-}
-
-TaskQueueManager::~TaskQueueManager() {
- TRACE_EVENT_OBJECT_DELETED_WITH_ID(disabled_by_default_tracing_category_,
- "TaskQueueManager", this);
- for (auto& queue : queues_)
- queue->WillDeleteTaskQueueManager();
- selector_->SetTaskQueueSelectorObserver(nullptr);
-}
-
-internal::TaskQueueImpl* TaskQueueManager::Queue(size_t queue_index) const {
- DCHECK_LT(queue_index, queues_.size());
- return queues_[queue_index].get();
-}
-
-scoped_refptr<TaskQueue> TaskQueueManager::TaskRunnerForQueue(
- size_t queue_index) const {
- return Queue(queue_index);
-}
-
-bool TaskQueueManager::IsQueueEmpty(size_t queue_index) const {
- return Queue(queue_index)->GetQueueState() == QueueState::EMPTY;
-}
-
-TaskQueueManager::QueueState TaskQueueManager::GetQueueState(size_t queue_index)
- const {
- return Queue(queue_index)->GetQueueState();
-}
-
-base::TimeTicks TaskQueueManager::NextPendingDelayedTaskRunTime() {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- bool found_pending_task = false;
- base::TimeTicks next_pending_delayed_task(
- base::TimeTicks::FromInternalValue(kMaxTimeTicks));
- for (auto& queue : queues_) {
- base::TimeTicks queues_next_pending_delayed_task;
- if (queue->NextPendingDelayedTaskRunTime(
- &queues_next_pending_delayed_task)) {
- found_pending_task = true;
- next_pending_delayed_task =
- std::min(next_pending_delayed_task, queues_next_pending_delayed_task);
- }
- }
-
- if (!found_pending_task)
- return base::TimeTicks();
-
- DCHECK_NE(next_pending_delayed_task,
- base::TimeTicks::FromInternalValue(kMaxTimeTicks));
- return next_pending_delayed_task;
-}
-
-void TaskQueueManager::SetPumpPolicy(size_t queue_index,
- PumpPolicy pump_policy) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- internal::TaskQueueImpl* queue = Queue(queue_index);
- queue->SetPumpPolicy(pump_policy);
-}
-
-void TaskQueueManager::SetWakeupPolicy(size_t queue_index,
- WakeupPolicy wakeup_policy) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- internal::TaskQueueImpl* queue = Queue(queue_index);
- queue->set_wakeup_policy(wakeup_policy);
-}
-
-void TaskQueueManager::PumpQueue(size_t queue_index) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- internal::TaskQueueImpl* queue = Queue(queue_index);
- queue->PumpQueue();
-}
-
-bool TaskQueueManager::UpdateWorkQueues(
- bool should_trigger_wakeup,
- const base::PendingTask* previous_task) {
- // TODO(skyostil): This is not efficient when the number of queues grows very
- // large due to the number of locks taken. Consider optimizing when we get
- // there.
- DCHECK(main_thread_checker_.CalledOnValidThread());
- internal::LazyNow lazy_now(this);
- bool has_work = false;
- for (auto& queue : queues_) {
- has_work |=
- queue->UpdateWorkQueue(&lazy_now, should_trigger_wakeup, previous_task);
- if (!queue->work_queue().empty()) {
- // Currently we should not be getting tasks with delayed run times in any
- // of the work queues.
- DCHECK(queue->work_queue().front().delayed_run_time.is_null());
- }
- }
- return has_work;
-}
-
-void TaskQueueManager::MaybePostDoWorkOnMainRunner() {
- bool on_main_thread = main_task_runner_->BelongsToCurrentThread();
- if (on_main_thread) {
- // We only want one pending DoWork posted from the main thread, or we risk
- // an explosion of pending DoWorks which could starve out everything else.
- if (pending_dowork_count_ > 0) {
- return;
- }
- pending_dowork_count_++;
- main_task_runner_->PostTask(FROM_HERE, do_work_from_main_thread_closure_);
- } else {
- main_task_runner_->PostTask(FROM_HERE, do_work_from_other_thread_closure_);
- }
-}
-
-void TaskQueueManager::DoWork(bool posted_from_main_thread) {
- if (posted_from_main_thread) {
- pending_dowork_count_--;
- DCHECK_GE(pending_dowork_count_, 0);
- }
- DCHECK(main_thread_checker_.CalledOnValidThread());
-
- // Pass false and nullptr to UpdateWorkQueues here to prevent waking up a
- // pump-after-wakeup queue.
- if (!UpdateWorkQueues(false, nullptr))
- return;
-
- base::PendingTask previous_task((tracked_objects::Location()),
- (base::Closure()));
- for (int i = 0; i < work_batch_size_; i++) {
- size_t queue_index;
- if (!SelectWorkQueueToService(&queue_index))
- return;
- // Note that this function won't post another call to DoWork if one is
- // already pending, so it is safe to call it in a loop.
- MaybePostDoWorkOnMainRunner();
-
- if (ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task))
- return; // The TaskQueueManager got deleted, we must bail out.
-
- bool should_trigger_wakeup = Queue(queue_index)->wakeup_policy() ==
- WakeupPolicy::CAN_WAKE_OTHER_QUEUES;
- if (!UpdateWorkQueues(should_trigger_wakeup, &previous_task))
- return;
- }
-}
-
-bool TaskQueueManager::SelectWorkQueueToService(size_t* out_queue_index) {
- bool should_run = selector_->SelectWorkQueueToService(out_queue_index);
- TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
- disabled_by_default_tracing_category_, "TaskQueueManager", this,
- AsValueWithSelectorResult(should_run, *out_queue_index));
- return should_run;
-}
-
-void TaskQueueManager::DidQueueTask(const base::PendingTask& pending_task) {
- task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task);
-}
-
-bool TaskQueueManager::ProcessTaskFromWorkQueue(
- size_t queue_index,
- bool has_previous_task,
- base::PendingTask* previous_task) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- scoped_refptr<DeletionSentinel> protect(deletion_sentinel_);
- internal::TaskQueueImpl* queue = Queue(queue_index);
- base::PendingTask pending_task = queue->TakeTaskFromWorkQueue();
- task_was_run_bitmap_ |= UINT64_C(1) << queue_index;
- if (!pending_task.nestable && main_task_runner_->IsNested()) {
- // Defer non-nestable work to the main task runner. NOTE these tasks can be
- // arbitrarily delayed so the additional delay should not be a problem.
- main_task_runner_->PostNonNestableTask(pending_task.posted_from,
- pending_task.task);
- } else {
- // Suppress "will" task observer notifications for the first and "did"
- // notifications for the last task in the batch to avoid duplicate
- // notifications.
- if (has_previous_task) {
- FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_,
- DidProcessTask(*previous_task));
- FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_,
- WillProcessTask(pending_task));
- }
- task_annotator_.RunTask("TaskQueueManager::PostTask",
- "TaskQueueManager::RunTask", pending_task);
-
- // Detect if the TaskQueueManager just got deleted. If this happens we must
- // not access any member variables after this point.
- if (protect->HasOneRef())
- return true;
-
- pending_task.task.Reset();
- *previous_task = pending_task;
- }
- return false;
-}
-
-bool TaskQueueManager::RunsTasksOnCurrentThread() const {
- return main_task_runner_->RunsTasksOnCurrentThread();
-}
-
-bool TaskQueueManager::PostDelayedTask(
- const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay) {
- DCHECK_GE(delay, base::TimeDelta());
- return main_task_runner_->PostDelayedTask(from_here, task, delay);
-}
-
-void TaskQueueManager::SetQueueName(size_t queue_index, const char* name) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- internal::TaskQueueImpl* queue = Queue(queue_index);
- queue->set_name(name);
-}
-
-void TaskQueueManager::SetWorkBatchSize(int work_batch_size) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- DCHECK_GE(work_batch_size, 1);
- work_batch_size_ = work_batch_size;
-}
-
-void TaskQueueManager::AddTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- main_task_runner_->AddTaskObserver(task_observer);
- task_observers_.AddObserver(task_observer);
-}
-
-void TaskQueueManager::RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- main_task_runner_->RemoveTaskObserver(task_observer);
- task_observers_.RemoveObserver(task_observer);
-}
-
-void TaskQueueManager::SetTimeSourceForTesting(
- scoped_ptr<base::TickClock> time_source) {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- time_source_ = time_source.Pass();
-}
-
-uint64 TaskQueueManager::GetAndClearTaskWasRunOnQueueBitmap() {
- uint64 bitmap = task_was_run_bitmap_;
- task_was_run_bitmap_ = 0;
- return bitmap;
-}
-
-base::TimeTicks TaskQueueManager::Now() const {
- return time_source_->NowTicks();
-}
-
-int TaskQueueManager::GetNextSequenceNumber() {
- return task_sequence_num_.GetNext();
-}
-
-scoped_refptr<base::trace_event::ConvertableToTraceFormat>
-TaskQueueManager::AsValueWithSelectorResult(bool should_run,
- size_t selected_queue) const {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- scoped_refptr<base::trace_event::TracedValue> state =
- new base::trace_event::TracedValue();
- state->BeginArray("queues");
- for (auto& queue : queues_)
- queue->AsValueInto(state.get());
- state->EndArray();
- state->BeginDictionary("selector");
- selector_->AsValueInto(state.get());
- state->EndDictionary();
- if (should_run)
- state->SetInteger("selected_queue", selected_queue);
- return state;
-}
-
-// static
-const char* TaskQueueManager::PumpPolicyToString(
- TaskQueueManager::PumpPolicy pump_policy) {
- switch (pump_policy) {
- case TaskQueueManager::PumpPolicy::AUTO:
- return "auto";
- case TaskQueueManager::PumpPolicy::AFTER_WAKEUP:
- return "after_wakeup";
- case TaskQueueManager::PumpPolicy::MANUAL:
- return "manual";
- default:
- NOTREACHED();
- return nullptr;
- }
-}
-
-// static
-const char* TaskQueueManager::WakeupPolicyToString(
- TaskQueueManager::WakeupPolicy wakeup_policy) {
- switch (wakeup_policy) {
- case TaskQueueManager::WakeupPolicy::CAN_WAKE_OTHER_QUEUES:
- return "can_wake_other_queues";
- case TaskQueueManager::WakeupPolicy::DONT_WAKE_OTHER_QUEUES:
- return "dont_wake_other_queues";
- default:
- NOTREACHED();
- return nullptr;
- }
-}
-
-void TaskQueueManager::OnTaskQueueEnabled() {
- DCHECK(main_thread_checker_.CalledOnValidThread());
- MaybePostDoWorkOnMainRunner();
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/child/task_queue_manager.h b/chromium/components/scheduler/child/task_queue_manager.h
deleted file mode 100644
index 3b8e5148925..00000000000
--- a/chromium/components/scheduler/child/task_queue_manager.h
+++ /dev/null
@@ -1,265 +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 CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
-#define CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
-
-#include "base/atomic_sequence_num.h"
-#include "base/debug/task_annotator.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/pending_task.h"
-#include "base/synchronization/lock.h"
-#include "base/threading/thread_checker.h"
-#include "components/scheduler/child/task_queue_selector.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace base {
-namespace trace_event {
-class ConvertableToTraceFormat;
-class TracedValue;
-}
-class TickClock;
-}
-
-namespace scheduler {
-class TaskQueue;
-namespace internal {
-class LazyNow;
-class TaskQueueImpl;
-}
-class NestableSingleThreadTaskRunner;
-class TaskQueueSelector;
-
-// The task queue manager provides N task queues and a selector interface for
-// choosing which task queue to service next. Each task queue consists of two
-// sub queues:
-//
-// 1. Incoming task queue. Tasks that are posted get immediately appended here.
-// When a task is appended into an empty incoming queue, the task manager
-// work function (DoWork) is scheduled to run on the main task runner.
-//
-// 2. Work queue. If a work queue is empty when DoWork() is entered, tasks from
-// the incoming task queue (if any) are moved here. The work queues are
-// registered with the selector as input to the scheduling decision.
-//
-class SCHEDULER_EXPORT TaskQueueManager : public TaskQueueSelector::Observer {
- public:
- // Keep TaskQueue::PumpPolicyToString in sync with this enum.
- enum class PumpPolicy {
- // Tasks posted to an incoming queue with an AUTO pump policy will be
- // automatically scheduled for execution or transferred to the work queue
- // automatically.
- AUTO,
- // Tasks posted to an incoming queue with an AFTER_WAKEUP pump policy
- // will be scheduled for execution or transferred to the work queue
- // automatically but only after another queue has executed a task.
- AFTER_WAKEUP,
- // Tasks posted to an incoming queue with a MANUAL will not be
- // automatically scheduled for execution or transferred to the work queue.
- // Instead, the selector should call PumpQueue() when necessary to bring
- // in new tasks for execution.
- MANUAL,
- // Must be last entry.
- PUMP_POLICY_COUNT,
- FIRST_PUMP_POLICY = AUTO,
- };
-
- // Keep TaskQueue::WakeupPolicyToString in sync with this enum.
- enum class WakeupPolicy {
- // Tasks run on a queue with CAN_WAKE_OTHER_QUEUES wakeup policy can
- // cause queues with the AFTER_WAKEUP PumpPolicy to be woken up.
- CAN_WAKE_OTHER_QUEUES,
- // Tasks run on a queue with DONT_WAKE_OTHER_QUEUES won't cause queues
- // with the AFTER_WAKEUP PumpPolicy to be woken up.
- DONT_WAKE_OTHER_QUEUES,
- // Must be last entry.
- WAKEUP_POLICY_COUNT,
- FIRST_WAKEUP_POLICY = CAN_WAKE_OTHER_QUEUES,
- };
-
- enum class QueueState {
- // A queue in the EMPTY state is empty and has no tasks in either the
- // work or incoming task queue.
- EMPTY,
- // A queue in the NEEDS_PUMPING state has no tasks in the work task queue,
- // but has tasks in the incoming task queue which can be pumped to make them
- // runnable.
- NEEDS_PUMPING,
- // A queue in the HAS_WORK state has tasks in the work task queue which
- // are runnable.
- HAS_WORK,
- };
-
- // Create a task queue manager with |task_queue_count| task queues.
- // |main_task_runner| identifies the thread on which where the tasks are
- // eventually run. |selector| is used to choose which task queue to service.
- // It should outlive this class. Category strings must have application
- // lifetime (statics or literals). They may not include " chars.
- TaskQueueManager(
- size_t task_queue_count,
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
- TaskQueueSelector* selector,
- const char* disabled_by_default_tracing_category,
- const char* disabled_by_default_verbose_tracing_category);
- ~TaskQueueManager() override;
-
- // Returns the task runner which targets the queue selected by |queue_index|.
- scoped_refptr<TaskQueue> TaskRunnerForQueue(size_t queue_index) const;
-
- // Sets the pump policy for the |queue_index| to |pump_policy|. By
- // default queues are created with AUTO_PUMP_POLICY.
- void SetPumpPolicy(size_t queue_index, PumpPolicy pump_policy);
-
- // Sets the wakeup policy for the |queue_index| to |wakeup_policy|. By
- // default queues are created with CAN_WAKE_OTHER_QUEUES.
- void SetWakeupPolicy(size_t queue_index, WakeupPolicy wakeup_policy);
-
- // Reloads new tasks from the incoming queue for |queue_index| into the work
- // queue, regardless of whether the work queue is empty or not. After this,
- // this function ensures that the tasks in the work queue, if any, are
- // scheduled for execution.
- //
- // This function only needs to be called if automatic pumping is disabled
- // for |queue_index|. See |SetQueueAutoPumpPolicy|. By default automatic
- // pumping is enabled for all queues.
- void PumpQueue(size_t queue_index);
-
- // Returns true if there no tasks in either the work or incoming task queue
- // identified by |queue_index|. Note that this function involves taking a
- // lock, so calling it has some overhead.
- bool IsQueueEmpty(size_t queue_index) const;
-
- // Returns the QueueState of the queue identified by |queue_index|. Note that
- // this function involves taking a lock, so calling it has some overhead.
- QueueState GetQueueState(size_t queue_index) const;
-
- // Returns the time of the next pending delayed task in any queue. Ignores
- // any delayed tasks whose delay has expired. Returns a null TimeTicks object
- // if no tasks are pending. NOTE this is somewhat expensive since every queue
- // will get locked.
- base::TimeTicks NextPendingDelayedTaskRunTime();
-
- // Set the name |queue_index| for tracing purposes. |name| must be a pointer
- // to a static string.
- void SetQueueName(size_t queue_index, const char* name);
-
- // Set the number of tasks executed in a single invocation of the task queue
- // manager. Increasing the batch size can reduce the overhead of yielding
- // back to the main message loop -- at the cost of potentially delaying other
- // tasks posted to the main loop. The batch size is 1 by default.
- void SetWorkBatchSize(int work_batch_size);
-
- // These functions can only be called on the same thread that the task queue
- // manager executes its tasks on.
- void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer);
- void RemoveTaskObserver(base::MessageLoop::TaskObserver* task_observer);
-
- void SetTimeSourceForTesting(scoped_ptr<base::TickClock> time_source);
-
- // Returns a bitmap where a bit is set iff a task on the corresponding queue
- // was run since the last call to GetAndClearTaskWasRunOnQueueBitmap.
- uint64 GetAndClearTaskWasRunOnQueueBitmap();
-
- private:
- // TaskQueueSelector::Observer implementation:
- void OnTaskQueueEnabled() override;
-
- friend class internal::LazyNow;
- friend class internal::TaskQueueImpl;
- friend class TaskQueueManagerTest;
-
- class DeletionSentinel : public base::RefCounted<DeletionSentinel> {
- private:
- friend class base::RefCounted<DeletionSentinel>;
- ~DeletionSentinel() {}
- };
-
- // Called by the task queue to register a new pending task.
- void DidQueueTask(const base::PendingTask& pending_task);
-
- // Post a task to call DoWork() on the main task runner. Only one pending
- // DoWork is allowed from the main thread, to prevent an explosion of pending
- // DoWorks.
- void MaybePostDoWorkOnMainRunner();
-
- // Use the selector to choose a pending task and run it.
- void DoWork(bool posted_from_main_thread);
-
- // Delayed Tasks with run_times <= Now() are enqueued onto the work queue.
- // Reloads any empty work queues which have automatic pumping enabled and
- // which are eligible to be auto pumped based on the |previous_task| which was
- // run and |should_trigger_wakeup| . Call with an empty |previous_task| if no
- // task was just run. Returns true if any work queue has tasks after doing
- // this.
- bool UpdateWorkQueues(bool should_trigger_wakeup,
- const base::PendingTask* previous_task);
-
- // Chooses the next work queue to service. Returns true if |out_queue_index|
- // indicates the queue from which the next task should be run, false to
- // avoid running any tasks.
- bool SelectWorkQueueToService(size_t* out_queue_index);
-
- // Runs a single nestable task from the work queue designated by
- // |queue_index|. If |has_previous_task| is true, |previous_task| should
- // contain the previous task in this work batch. Non-nestable task are
- // reposted on the run loop. The queue must not be empty.
- // Returns true if the TaskQueueManager got deleted, and false otherwise.
- bool ProcessTaskFromWorkQueue(size_t queue_index,
- bool has_previous_task,
- base::PendingTask* previous_task);
-
- bool RunsTasksOnCurrentThread() const;
- bool PostDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay);
- bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay);
- internal::TaskQueueImpl* Queue(size_t queue_index) const;
-
- base::TimeTicks Now() const;
-
- int GetNextSequenceNumber();
-
- scoped_refptr<base::trace_event::ConvertableToTraceFormat>
- AsValueWithSelectorResult(bool should_run, size_t selected_queue) const;
- static const char* PumpPolicyToString(PumpPolicy pump_policy);
- static const char* WakeupPolicyToString(WakeupPolicy wakeup_policy);
-
- std::vector<scoped_refptr<internal::TaskQueueImpl>> queues_;
- base::AtomicSequenceNumber task_sequence_num_;
- base::debug::TaskAnnotator task_annotator_;
-
- base::ThreadChecker main_thread_checker_;
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner_;
- TaskQueueSelector* selector_;
-
- base::Closure do_work_from_main_thread_closure_;
- base::Closure do_work_from_other_thread_closure_;
-
- uint64 task_was_run_bitmap_;
-
- // The pending_dowork_count_ is only tracked on the main thread since that's
- // where re-entrant problems happen.
- int pending_dowork_count_;
-
- int work_batch_size_;
-
- scoped_ptr<base::TickClock> time_source_;
-
- base::ObserverList<base::MessageLoop::TaskObserver> task_observers_;
-
- const char* disabled_by_default_tracing_category_;
-
- scoped_refptr<DeletionSentinel> deletion_sentinel_;
- base::WeakPtrFactory<TaskQueueManager> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(TaskQueueManager);
-};
-
-} // namespace scheduler
-
-#endif // CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
diff --git a/chromium/components/scheduler/child/task_queue_manager_unittest.cc b/chromium/components/scheduler/child/task_queue_manager_unittest.cc
deleted file mode 100644
index 8b6839b20c0..00000000000
--- a/chromium/components/scheduler/child/task_queue_manager_unittest.cc
+++ /dev/null
@@ -1,1331 +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/scheduler/child/task_queue_manager.h"
-
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/threading/thread.h"
-#include "cc/test/ordered_simple_task_runner.h"
-#include "components/scheduler/child/nestable_task_runner_for_test.h"
-#include "components/scheduler/child/scheduler_message_loop_delegate.h"
-#include "components/scheduler/child/task_queue.h"
-#include "components/scheduler/child/task_queue_selector.h"
-#include "components/scheduler/child/test_time_source.h"
-#include "components/scheduler/test/test_always_fail_time_source.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-using testing::ElementsAre;
-using testing::_;
-
-namespace scheduler {
-namespace {
-
-class SelectorForTest : public TaskQueueSelector {
- public:
- ~SelectorForTest() override {}
-
- virtual void AppendQueueToService(size_t queue_index) = 0;
-
- virtual const std::vector<const base::TaskQueue*>& work_queues() = 0;
-
- void AsValueInto(base::trace_event::TracedValue* state) const override {}
-};
-
-// Always selects the oldest non-empty queue.
-class AutomaticSelectorForTest : public SelectorForTest {
- public:
- AutomaticSelectorForTest() {}
- ~AutomaticSelectorForTest() override {}
-
- void RegisterWorkQueues(
- const std::vector<const base::TaskQueue*>& work_queues) override {
- work_queues_ = work_queues;
- }
-
- bool SelectWorkQueueToService(size_t* out_queue_index) override {
- size_t oldest = (size_t) kInvalidIndex;
- for (size_t i = 0; i < work_queues_.size(); i++) {
- if (work_queues_[i]->empty())
- continue;
- // Note the TaskQueue < operator actually implements > hence the odd
- // comparison below.
- if (oldest == kInvalidIndex ||
- work_queues_[oldest]->front() < work_queues_[i]->front()) {
- oldest = i;
- }
- }
- if (oldest != kInvalidIndex) {
- *out_queue_index = oldest;
- return true;
- }
- return false;
- }
-
- void AppendQueueToService(size_t queue_index) override {
- DCHECK(false) << "Not supported";
- }
-
- const std::vector<const base::TaskQueue*>& work_queues() override {
- return work_queues_;
- }
-
- void SetTaskQueueSelectorObserver(Observer* observer) override {}
-
- private:
- std::vector<const base::TaskQueue*> work_queues_;
-
- enum { kInvalidIndex = 0xffffffff };
-
- DISALLOW_COPY_AND_ASSIGN(AutomaticSelectorForTest);
-};
-
-class ExplicitSelectorForTest : public SelectorForTest {
- public:
- ExplicitSelectorForTest() {}
- ~ExplicitSelectorForTest() override {}
-
- void RegisterWorkQueues(
- const std::vector<const base::TaskQueue*>& work_queues) override {
- work_queues_ = work_queues;
- }
-
- bool SelectWorkQueueToService(size_t* out_queue_index) override {
- if (queues_to_service_.empty())
- return false;
- *out_queue_index = queues_to_service_.front();
- queues_to_service_.pop_front();
- return true;
- }
-
- void AppendQueueToService(size_t queue_index) override {
- queues_to_service_.push_back(queue_index);
- }
-
- const std::vector<const base::TaskQueue*>& work_queues() override {
- return work_queues_;
- }
-
- void SetTaskQueueSelectorObserver(Observer* observer) override {}
-
- private:
- std::deque<size_t> queues_to_service_;
- std::vector<const base::TaskQueue*> work_queues_;
-
- DISALLOW_COPY_AND_ASSIGN(ExplicitSelectorForTest);
-};
-
-} // namespace
-
-class TaskQueueManagerTest : public testing::Test {
- public:
- void DeleteTaskQueueManager() { manager_.reset(); }
-
- protected:
- enum class SelectorType {
- Automatic,
- Explicit,
- };
-
- void Initialize(size_t num_queues, SelectorType type) {
- now_src_.reset(new base::SimpleTestTickClock());
- now_src_->Advance(base::TimeDelta::FromMicroseconds(1000));
- test_task_runner_ = make_scoped_refptr(
- new cc::OrderedSimpleTaskRunner(now_src_.get(), false));
- selector_ = make_scoped_ptr(createSelectorForTest(type));
- manager_ = make_scoped_ptr(new TaskQueueManager(
- num_queues, NestableTaskRunnerForTest::Create(test_task_runner_.get()),
- selector_.get(), "test.scheduler", "test.scheduler.debug"));
- manager_->SetTimeSourceForTesting(
- make_scoped_ptr(new TestTimeSource(now_src_.get())));
-
- EXPECT_EQ(num_queues, selector_->work_queues().size());
- }
-
- void InitializeWithRealMessageLoop(size_t num_queues, SelectorType type) {
- message_loop_.reset(new base::MessageLoop());
- selector_ = make_scoped_ptr(createSelectorForTest(type));
- manager_ = make_scoped_ptr(new TaskQueueManager(
- num_queues, SchedulerMessageLoopDelegate::Create(message_loop_.get()),
- selector_.get(), "test.scheduler", "test.scheduler.debug"));
- EXPECT_EQ(num_queues, selector_->work_queues().size());
- }
-
- SelectorForTest* createSelectorForTest(SelectorType type) {
- switch (type) {
- case SelectorType::Automatic:
- return new AutomaticSelectorForTest();
-
- case SelectorType::Explicit:
- return new ExplicitSelectorForTest();
- }
-
- return nullptr;
- }
-
- template <typename E>
- static void CallForEachEnumValue(E first,
- E last,
- const char* (*function)(E)) {
- for (E val = first; val < last;
- val = static_cast<E>(static_cast<int>(val) + 1)) {
- (*function)(val);
- }
- }
-
- static void CheckAllPumpPolicyToString() {
- CallForEachEnumValue<TaskQueueManager::PumpPolicy>(
- TaskQueueManager::PumpPolicy::FIRST_PUMP_POLICY,
- TaskQueueManager::PumpPolicy::PUMP_POLICY_COUNT,
- &TaskQueueManager::PumpPolicyToString);
- }
-
- static void CheckAllWakeupPolicyToString() {
- CallForEachEnumValue<TaskQueueManager::WakeupPolicy>(
- TaskQueueManager::WakeupPolicy::FIRST_WAKEUP_POLICY,
- TaskQueueManager::WakeupPolicy::WAKEUP_POLICY_COUNT,
- &TaskQueueManager::WakeupPolicyToString);
- }
-
- scoped_ptr<base::SimpleTestTickClock> now_src_;
- scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner_;
- scoped_ptr<SelectorForTest> selector_;
- scoped_ptr<TaskQueueManager> manager_;
- scoped_ptr<base::MessageLoop> message_loop_;
-};
-
-void PostFromNestedRunloop(base::MessageLoop* message_loop,
- base::SingleThreadTaskRunner* runner,
- std::vector<std::pair<base::Closure, bool>>* tasks) {
- base::MessageLoop::ScopedNestableTaskAllower allow(message_loop);
- for (std::pair<base::Closure, bool>& pair : *tasks) {
- if (pair.second) {
- runner->PostTask(FROM_HERE, pair.first);
- } else {
- runner->PostNonNestableTask(FROM_HERE, pair.first);
- }
- }
- message_loop->RunUntilIdle();
-}
-
-void NullTask() {
-}
-
-void TestTask(int value, std::vector<int>* out_result) {
- out_result->push_back(value);
-}
-
-TEST_F(TaskQueueManagerTest, SingleQueuePosting) {
- Initialize(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
-}
-
-TEST_F(TaskQueueManagerTest, MultiQueuePosting) {
- Initialize(3u, SelectorType::Explicit);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runners[3] = {
- manager_->TaskRunnerForQueue(0),
- manager_->TaskRunnerForQueue(1),
- manager_->TaskRunnerForQueue(2)};
-
- selector_->AppendQueueToService(0);
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(2);
- selector_->AppendQueueToService(0);
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(2);
-
- runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
- runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order));
- runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1, 3, 5, 2, 4, 6));
-}
-
-void NopTask() {
-}
-
-TEST_F(TaskQueueManagerTest, NowNotCalledWhenThereAreNoDelayedTasks) {
- Initialize(3u, SelectorType::Explicit);
-
- manager_->SetTimeSourceForTesting(
- make_scoped_ptr(new TestAlwaysFailTimeSource()));
-
- scoped_refptr<base::SingleThreadTaskRunner> runners[3] = {
- manager_->TaskRunnerForQueue(0),
- manager_->TaskRunnerForQueue(1),
- manager_->TaskRunnerForQueue(2)};
-
- selector_->AppendQueueToService(0);
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(2);
- selector_->AppendQueueToService(0);
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(2);
-
- runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners[2]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners[2]->PostTask(FROM_HERE, base::Bind(&NopTask));
-
- test_task_runner_->RunUntilIdle();
-}
-
-TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) {
- InitializeWithRealMessageLoop(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostNonNestableTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
-
- message_loop_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, NonNestableTaskExecutesInExpectedOrder) {
- InitializeWithRealMessageLoop(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
- runner->PostNonNestableTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order));
-
- message_loop_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5));
-}
-
-TEST_F(TaskQueueManagerTest, NonNestableTaskDoesntExecuteInNestedLoop) {
- InitializeWithRealMessageLoop(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
-
- std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&TestTask, 3, &run_order), false));
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&TestTask, 4, &run_order), true));
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&TestTask, 5, &run_order), true));
-
- runner->PostTask(
- FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(), runner,
- base::Unretained(&tasks_to_post_from_nested_loop)));
-
- message_loop_->RunUntilIdle();
- // Note we expect task 3 to run last because it's non-nestable.
- EXPECT_THAT(run_order, ElementsAre(1, 2, 4, 5, 3));
-}
-
-TEST_F(TaskQueueManagerTest, QueuePolling) {
- Initialize(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- EXPECT_TRUE(manager_->IsQueueEmpty(0));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- EXPECT_FALSE(manager_->IsQueueEmpty(0));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(manager_->IsQueueEmpty(0));
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskPosting) {
- Initialize(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
- EXPECT_EQ(delay, test_task_runner_->DelayToNextTaskTime());
- EXPECT_TRUE(manager_->IsQueueEmpty(0));
- EXPECT_TRUE(run_order.empty());
-
- // The task doesn't run before the delay has completed.
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(9));
- EXPECT_TRUE(run_order.empty());
-
- // After the delay has completed, the task runs normally.
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) {
- Initialize(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- base::TimeDelta::FromMilliseconds(10));
-
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- base::TimeDelta::FromMilliseconds(8));
-
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- base::TimeDelta::FromMilliseconds(5));
-
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(5),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
- EXPECT_THAT(run_order, ElementsAre(3));
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(3),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(3));
- EXPECT_THAT(run_order, ElementsAre(3, 2));
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(2),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(2));
- EXPECT_THAT(run_order, ElementsAre(3, 2, 1));
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) {
- Initialize(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- base::TimeDelta::FromMilliseconds(1));
-
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- base::TimeDelta::FromMilliseconds(5));
-
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- base::TimeDelta::FromMilliseconds(10));
-
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(1),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
- EXPECT_THAT(run_order, ElementsAre(1));
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(4),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(4));
- EXPECT_THAT(run_order, ElementsAre(1, 2));
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(5),
- test_task_runner_->DelayToNextTaskTime());
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
-}
-
-TEST_F(TaskQueueManagerTest, PostDelayedTask_SharesUnderlyingDelayedTasks) {
- Initialize(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- delay);
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- delay);
-
- EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
-}
-
-class TestObject {
- public:
- ~TestObject() { destructor_count_++; }
-
- void Run() { FAIL() << "TestObject::Run should not be called"; }
-
- static int destructor_count_;
-};
-
-int TestObject::destructor_count_ = 0;
-
-TEST_F(TaskQueueManagerTest, PendingDelayedTasksRemovedOnShutdown) {
- Initialize(1u, SelectorType::Automatic);
-
- TestObject::destructor_count_ = 0;
-
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runner->PostDelayedTask(
- FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())),
- delay);
- runner->PostTask(FROM_HERE,
- base::Bind(&TestObject::Run, base::Owned(new TestObject())));
-
- manager_.reset();
-
- EXPECT_EQ(2, TestObject::destructor_count_);
-}
-
-TEST_F(TaskQueueManagerTest, ManualPumping) {
- Initialize(1u, SelectorType::Automatic);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- // Posting a task when pumping is disabled doesn't result in work getting
- // posted.
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- EXPECT_FALSE(test_task_runner_->HasPendingTasks());
-
- // However polling still works.
- EXPECT_FALSE(manager_->IsQueueEmpty(0));
-
- // After pumping the task runs normally.
- manager_->PumpQueue(0);
- EXPECT_TRUE(test_task_runner_->HasPendingTasks());
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, ManualPumpingToggle) {
- Initialize(1u, SelectorType::Automatic);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- // Posting a task when pumping is disabled doesn't result in work getting
- // posted.
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- EXPECT_FALSE(test_task_runner_->HasPendingTasks());
-
- // When pumping is enabled the task runs normally.
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AUTO);
- EXPECT_TRUE(test_task_runner_->HasPendingTasks());
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, DenyRunning) {
- Initialize(1u, SelectorType::Explicit);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
-
- // Since we haven't appended a work queue to be selected, the task doesn't
- // run.
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- // Pumping the queue again with a selected work queue runs the task.
- manager_->PumpQueue(0);
- selector_->AppendQueueToService(0);
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, ManualPumpingWithDelayedTask) {
- Initialize(1u, SelectorType::Automatic);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- // Posting a delayed task when pumping will apply the delay, but won't cause
- // work to executed afterwards.
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
-
- // After pumping but before the delay period has expired, task does not run.
- manager_->PumpQueue(0);
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
- EXPECT_TRUE(run_order.empty());
-
- // Once the delay has expired, pumping causes the task to run.
- now_src_->Advance(base::TimeDelta::FromMilliseconds(5));
- manager_->PumpQueue(0);
- EXPECT_TRUE(test_task_runner_->HasPendingTasks());
- test_task_runner_->RunPendingTasks();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-TEST_F(TaskQueueManagerTest, ManualPumpingWithMultipleDelayedTasks) {
- Initialize(1u, SelectorType::Automatic);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- // Posting a delayed task when pumping will apply the delay, but won't cause
- // work to executed afterwards.
- base::TimeDelta delay1(base::TimeDelta::FromMilliseconds(1));
- base::TimeDelta delay2(base::TimeDelta::FromMilliseconds(10));
- base::TimeDelta delay3(base::TimeDelta::FromMilliseconds(20));
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay1);
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- delay2);
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- delay3);
-
- now_src_->Advance(base::TimeDelta::FromMilliseconds(15));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- // Once the delay has expired, pumping causes the task to run.
- manager_->PumpQueue(0);
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1, 2));
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTasksDontAutoRunWithManualPumping) {
- Initialize(1u, SelectorType::Automatic);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
- runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
-
- test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(10));
- EXPECT_TRUE(run_order.empty());
-}
-
-TEST_F(TaskQueueManagerTest, ManualPumpingWithNonEmptyWorkQueue) {
- Initialize(1u, SelectorType::Automatic);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- // Posting two tasks and pumping twice should result in two tasks in the work
- // queue.
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- manager_->PumpQueue(0);
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- manager_->PumpQueue(0);
-
- EXPECT_EQ(2u, selector_->work_queues()[0]->size());
-}
-
-void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
- int countdown,
- std::vector<int>* out_result) {
- out_result->push_back(countdown);
- if (--countdown) {
- runner->PostTask(FROM_HERE,
- Bind(&ReentrantTestTask, runner, countdown, out_result));
- }
-}
-
-TEST_F(TaskQueueManagerTest, ReentrantPosting) {
- Initialize(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostTask(FROM_HERE, Bind(&ReentrantTestTask, runner, 3, &run_order));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(3, 2, 1));
-}
-
-TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) {
- Initialize(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- manager_.reset();
- selector_.reset();
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-}
-
-void PostTaskToRunner(scoped_refptr<base::SingleThreadTaskRunner> runner,
- std::vector<int>* run_order) {
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, run_order));
-}
-
-TEST_F(TaskQueueManagerTest, PostFromThread) {
- InitializeWithRealMessageLoop(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- base::Thread thread("TestThread");
- thread.Start();
- thread.task_runner()->PostTask(
- FROM_HERE, base::Bind(&PostTaskToRunner, runner, &run_order));
- thread.Stop();
-
- message_loop_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(1));
-}
-
-void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
- int* run_count) {
- (*run_count)++;
- runner->PostTask(FROM_HERE, Bind(&RePostingTestTask,
- base::Unretained(runner.get()), run_count));
-}
-
-TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) {
- Initialize(1u, SelectorType::Automatic);
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- int run_count = 0;
- runner->PostTask(FROM_HERE,
- base::Bind(&RePostingTestTask, runner, &run_count));
-
- test_task_runner_->RunPendingTasks();
- // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there
- // will be two tasks here.
- EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
- EXPECT_EQ(1, run_count);
-}
-
-TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) {
- InitializeWithRealMessageLoop(1u, SelectorType::Automatic);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
- tasks_to_post_from_nested_loop.push_back(
- std::make_pair(base::Bind(&TestTask, 1, &run_order), true));
-
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 0, &run_order));
- runner->PostTask(
- FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(), runner,
- base::Unretained(&tasks_to_post_from_nested_loop)));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
-
- message_loop_->RunUntilIdle();
-
- EXPECT_THAT(run_order, ElementsAre(0, 2, 1));
-}
-
-TEST_F(TaskQueueManagerTest, WorkBatching) {
- Initialize(1u, SelectorType::Automatic);
-
- manager_->SetWorkBatchSize(2);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
-
- // Running one task in the host message loop should cause two posted tasks to
- // get executed.
- EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u);
- test_task_runner_->RunPendingTasks();
- EXPECT_THAT(run_order, ElementsAre(1, 2));
-
- // The second task runs the remaining two posted tasks.
- EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u);
- test_task_runner_->RunPendingTasks();
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4));
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeup) {
- Initialize(2u, SelectorType::Explicit);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(0);
- selector_->AppendQueueToService(0);
-
- runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM.
-
- runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty()); // Still shouldn't wake TQM.
-
- runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- test_task_runner_->RunUntilIdle();
- // Executing a task on an auto pumped queue should wake the TQM.
- EXPECT_THAT(run_order, ElementsAre(3, 1, 2));
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWhenAlreadyAwake) {
- Initialize(2u, SelectorType::Explicit);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(0);
-
- runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(2, 1)); // TQM was already awake.
-}
-
-TEST_F(TaskQueueManagerTest,
- AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue) {
- Initialize(2u, SelectorType::Explicit);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
- manager_->SetPumpPolicy(1, TaskQueueManager::PumpPolicy::MANUAL);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(0);
-
- runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM.
-
- runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- test_task_runner_->RunUntilIdle();
- // This still shouldn't wake TQM as manual queue was not pumped.
- EXPECT_TRUE(run_order.empty());
-
- manager_->PumpQueue(1);
- test_task_runner_->RunUntilIdle();
- // Executing a task on an auto pumped queue should wake the TQM.
- EXPECT_THAT(run_order, ElementsAre(2, 1));
-}
-
-void TestPostingTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- base::Closure task) {
- task_runner->PostTask(FROM_HERE, task);
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromTask) {
- Initialize(2u, SelectorType::Explicit);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(0);
-
- // Check that a task which posts a task to an auto pump after wakeup queue
- // doesn't cause the queue to wake up.
- base::Closure after_wakeup_task = base::Bind(&TestTask, 1, &run_order);
- runners[1]->PostTask(
- FROM_HERE, base::Bind(&TestPostingTask, runners[0], after_wakeup_task));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- // Wake up the queue.
- runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(2, 1));
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromMultipleTasks) {
- Initialize(2u, SelectorType::Explicit);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(0);
- selector_->AppendQueueToService(0);
-
- // Check that a task which posts a task to an auto pump after wakeup queue
- // doesn't cause the queue to wake up.
- base::Closure after_wakeup_task_1 = base::Bind(&TestTask, 1, &run_order);
- base::Closure after_wakeup_task_2 = base::Bind(&TestTask, 2, &run_order);
- runners[1]->PostTask(
- FROM_HERE, base::Bind(&TestPostingTask, runners[0], after_wakeup_task_1));
- runners[1]->PostTask(
- FROM_HERE, base::Bind(&TestPostingTask, runners[0], after_wakeup_task_2));
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- // Wake up the queue.
- runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- test_task_runner_->RunUntilIdle();
- EXPECT_THAT(run_order, ElementsAre(3, 1, 2));
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupBecomesQuiescent) {
- Initialize(2u, SelectorType::Explicit);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
-
- int run_count = 0;
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(0);
- selector_->AppendQueueToService(0);
- // Append extra service queue '0' entries to the selector otherwise test will
- // finish even if the RePostingTestTask woke each other up.
- selector_->AppendQueueToService(0);
- selector_->AppendQueueToService(0);
-
- // Check that if multiple tasks reposts themselves onto a pump-after-wakeup
- // queue they don't wake each other and will eventually stop when no other
- // tasks execute.
- runners[0]->PostTask(FROM_HERE,
- base::Bind(&RePostingTestTask, runners[0], &run_count));
- runners[0]->PostTask(FROM_HERE,
- base::Bind(&RePostingTestTask, runners[0], &run_count));
- runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- // The reposting tasks posted to the after wakeup queue shouldn't have woken
- // each other up.
- EXPECT_EQ(2, run_count);
-}
-
-TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWithDontWakeQueue) {
- Initialize(3u, SelectorType::Explicit);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
- manager_->SetWakeupPolicy(1,
- TaskQueueManager::WakeupPolicy::DONT_WAKE_OTHER_QUEUES);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runners[3] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1),
- manager_->TaskRunnerForQueue(2)};
-
- selector_->AppendQueueToService(1);
- selector_->AppendQueueToService(2);
- selector_->AppendQueueToService(0);
-
- runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- test_task_runner_->RunUntilIdle();
- // Executing a DONT_WAKE_OTHER_QUEUES queue shouldn't wake the autopump after
- // wakeup queue.
- EXPECT_THAT(run_order, ElementsAre(2));
-
- runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
- test_task_runner_->RunUntilIdle();
- // Executing a CAN_WAKE_OTHER_QUEUES queue should wake the autopump after
- // wakeup queue.
- EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
-}
-
-class MockTaskObserver : public base::MessageLoop::TaskObserver {
- public:
- MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task));
- MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task));
-};
-
-TEST_F(TaskQueueManagerTest, TaskObserverAdding) {
- InitializeWithRealMessageLoop(1u, SelectorType::Automatic);
- MockTaskObserver observer;
-
- manager_->SetWorkBatchSize(2);
- manager_->AddTaskObserver(&observer);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
-
- // Two pairs of callbacks for the tasks above plus another one for the
- // DoWork() posted by the task queue manager.
- EXPECT_CALL(observer, WillProcessTask(_)).Times(3);
- EXPECT_CALL(observer, DidProcessTask(_)).Times(3);
- message_loop_->RunUntilIdle();
-}
-
-TEST_F(TaskQueueManagerTest, TaskObserverRemoving) {
- InitializeWithRealMessageLoop(1u, SelectorType::Automatic);
- MockTaskObserver observer;
- manager_->SetWorkBatchSize(2);
- manager_->AddTaskObserver(&observer);
- manager_->RemoveTaskObserver(&observer);
-
- std::vector<int> run_order;
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
-
- runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
-
- EXPECT_CALL(observer, WillProcessTask(_)).Times(0);
- EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
-
- message_loop_->RunUntilIdle();
-}
-
-void RemoveObserverTask(TaskQueueManager* manager,
- base::MessageLoop::TaskObserver* observer) {
- manager->RemoveTaskObserver(observer);
-}
-
-TEST_F(TaskQueueManagerTest, TaskObserverRemovingInsideTask) {
- InitializeWithRealMessageLoop(1u, SelectorType::Automatic);
- MockTaskObserver observer;
- manager_->SetWorkBatchSize(3);
- manager_->AddTaskObserver(&observer);
-
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
- runner->PostTask(FROM_HERE,
- base::Bind(&RemoveObserverTask, manager_.get(), &observer));
-
- EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
- EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
- message_loop_->RunUntilIdle();
-}
-
-TEST_F(TaskQueueManagerTest, ThreadCheckAfterTermination) {
- Initialize(1u, SelectorType::Automatic);
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
- EXPECT_TRUE(runner->RunsTasksOnCurrentThread());
- manager_.reset();
- EXPECT_TRUE(runner->RunsTasksOnCurrentThread());
-}
-
-TEST_F(TaskQueueManagerTest, NextPendingDelayedTaskRunTime) {
- scoped_ptr<base::SimpleTestTickClock> clock(new base::SimpleTestTickClock());
- clock->Advance(base::TimeDelta::FromMicroseconds(10000));
- Initialize(2u, SelectorType::Explicit);
- manager_->SetTimeSourceForTesting(
- make_scoped_ptr(new TestTimeSource(clock.get())));
-
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- // With no delayed tasks.
- EXPECT_TRUE(manager_->NextPendingDelayedTaskRunTime().is_null());
-
- // With a non-delayed task.
- runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
- EXPECT_TRUE(manager_->NextPendingDelayedTaskRunTime().is_null());
-
- // With a delayed task.
- base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(50);
- runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
- EXPECT_EQ(clock->NowTicks() + expected_delay,
- manager_->NextPendingDelayedTaskRunTime());
-
- // With another delayed task in the same queue with a longer delay.
- runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask),
- base::TimeDelta::FromMilliseconds(100));
- EXPECT_EQ(clock->NowTicks() + expected_delay,
- manager_->NextPendingDelayedTaskRunTime());
-
- // With another delayed task in the same queue with a shorter delay.
- expected_delay = base::TimeDelta::FromMilliseconds(20);
- runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
- EXPECT_EQ(clock->NowTicks() + expected_delay,
- manager_->NextPendingDelayedTaskRunTime());
-
- // With another delayed task in a different queue with a shorter delay.
- expected_delay = base::TimeDelta::FromMilliseconds(10);
- runners[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
- EXPECT_EQ(clock->NowTicks() + expected_delay,
- manager_->NextPendingDelayedTaskRunTime());
-
- // Test it updates as time progresses
- clock->Advance(expected_delay);
- EXPECT_EQ(clock->NowTicks(), manager_->NextPendingDelayedTaskRunTime());
-}
-
-TEST_F(TaskQueueManagerTest, NextPendingDelayedTaskRunTime_MultipleQueues) {
- Initialize(3u, SelectorType::Automatic);
-
- scoped_refptr<base::SingleThreadTaskRunner> runners[3] = {
- manager_->TaskRunnerForQueue(0),
- manager_->TaskRunnerForQueue(1),
- manager_->TaskRunnerForQueue(2)};
-
- base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50);
- base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5);
- base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(10);
- runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay1);
- runners[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay2);
- runners[2]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay3);
-
- EXPECT_EQ(now_src_->NowTicks() + delay2,
- manager_->NextPendingDelayedTaskRunTime());
-}
-
-TEST_F(TaskQueueManagerTest, DeleteTaskQueueManagerInsideATask) {
- Initialize(1u, SelectorType::Automatic);
-
- scoped_refptr<base::SingleThreadTaskRunner> runner =
- manager_->TaskRunnerForQueue(0);
- runner->PostTask(FROM_HERE,
- base::Bind(&TaskQueueManagerTest::DeleteTaskQueueManager,
- base::Unretained(this)));
-
- // This should not crash, assuming DoWork detects the TaskQueueManager has
- // been deleted.
- test_task_runner_->RunUntilIdle();
-}
-
-TEST_F(TaskQueueManagerTest, GetAndClearTaskWasRunBitmap) {
- Initialize(3u, SelectorType::Automatic);
-
- scoped_refptr<base::SingleThreadTaskRunner> runners[3] = {
- manager_->TaskRunnerForQueue(0),
- manager_->TaskRunnerForQueue(1),
- manager_->TaskRunnerForQueue(2)};
-
- EXPECT_EQ(0ul, manager_->GetAndClearTaskWasRunOnQueueBitmap());
-
- runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- EXPECT_EQ(1ul << 0, manager_->GetAndClearTaskWasRunOnQueueBitmap());
-
- runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- EXPECT_EQ(1ul << 1, manager_->GetAndClearTaskWasRunOnQueueBitmap());
-
- runners[2]->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- EXPECT_EQ(1ul << 2, manager_->GetAndClearTaskWasRunOnQueueBitmap());
-
- runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
- runners[2]->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- EXPECT_EQ(1ul << 0 | 1ul << 2,
- manager_->GetAndClearTaskWasRunOnQueueBitmap());
- EXPECT_EQ(0ul, manager_->GetAndClearTaskWasRunOnQueueBitmap());
-}
-
-TEST_F(TaskQueueManagerTest, GetAndClearTaskWasRunBitmap_ManyQueues) {
- Initialize(64u, SelectorType::Automatic);
-
- manager_->TaskRunnerForQueue(63)->PostTask(FROM_HERE, base::Bind(&NopTask));
- test_task_runner_->RunUntilIdle();
- EXPECT_EQ(1ull << 63, manager_->GetAndClearTaskWasRunOnQueueBitmap());
-}
-
-TEST_F(TaskQueueManagerTest, PumpPolicyToString) {
- CheckAllPumpPolicyToString();
-}
-
-TEST_F(TaskQueueManagerTest, WakeupPolicyToString) {
- CheckAllWakeupPolicyToString();
-}
-
-TEST_F(TaskQueueManagerTest, IsQueueEmpty) {
- Initialize(2u, SelectorType::Automatic);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AUTO);
- manager_->SetPumpPolicy(1, TaskQueueManager::PumpPolicy::MANUAL);
-
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- EXPECT_TRUE(manager_->IsQueueEmpty(0));
- EXPECT_TRUE(manager_->IsQueueEmpty(1));
-
- runners[0]->PostTask(FROM_HERE, base::Bind(NullTask));
- runners[1]->PostTask(FROM_HERE, base::Bind(NullTask));
- EXPECT_FALSE(manager_->IsQueueEmpty(0));
- EXPECT_FALSE(manager_->IsQueueEmpty(1));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(manager_->IsQueueEmpty(0));
- EXPECT_FALSE(manager_->IsQueueEmpty(1));
-
- manager_->PumpQueue(1);
- EXPECT_TRUE(manager_->IsQueueEmpty(0));
- EXPECT_FALSE(manager_->IsQueueEmpty(1));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_TRUE(manager_->IsQueueEmpty(0));
- EXPECT_TRUE(manager_->IsQueueEmpty(1));
-}
-
-TEST_F(TaskQueueManagerTest, GetQueueState) {
- Initialize(2u, SelectorType::Automatic);
- manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AUTO);
- manager_->SetPumpPolicy(1, TaskQueueManager::PumpPolicy::MANUAL);
-
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- EXPECT_EQ(TaskQueueManager::QueueState::EMPTY, manager_->GetQueueState(0));
- EXPECT_EQ(TaskQueueManager::QueueState::EMPTY, manager_->GetQueueState(1));
-
- runners[0]->PostTask(FROM_HERE, base::Bind(NullTask));
- runners[0]->PostTask(FROM_HERE, base::Bind(NullTask));
- runners[1]->PostTask(FROM_HERE, base::Bind(NullTask));
- EXPECT_EQ(TaskQueueManager::QueueState::NEEDS_PUMPING,
- manager_->GetQueueState(0));
- EXPECT_EQ(TaskQueueManager::QueueState::NEEDS_PUMPING,
- manager_->GetQueueState(1));
-
- test_task_runner_->SetRunTaskLimit(1);
- test_task_runner_->RunPendingTasks();
- EXPECT_EQ(TaskQueueManager::QueueState::HAS_WORK,
- manager_->GetQueueState(0));
- EXPECT_EQ(TaskQueueManager::QueueState::NEEDS_PUMPING,
- manager_->GetQueueState(1));
-
- test_task_runner_->ClearRunTaskLimit();
- test_task_runner_->RunUntilIdle();
- EXPECT_EQ(TaskQueueManager::QueueState::EMPTY,
- manager_->GetQueueState(0));
- EXPECT_EQ(TaskQueueManager::QueueState::NEEDS_PUMPING,
- manager_->GetQueueState(1));
-
- manager_->PumpQueue(1);
- EXPECT_EQ(TaskQueueManager::QueueState::EMPTY,
- manager_->GetQueueState(0));
- EXPECT_EQ(TaskQueueManager::QueueState::HAS_WORK,
- manager_->GetQueueState(1));
-
- test_task_runner_->RunUntilIdle();
- EXPECT_EQ(TaskQueueManager::QueueState::EMPTY,
- manager_->GetQueueState(0));
- EXPECT_EQ(TaskQueueManager::QueueState::EMPTY,
- manager_->GetQueueState(1));
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfNonDelayedTask) {
- Initialize(2u, SelectorType::Automatic);
-
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- std::vector<int> run_order;
-
- base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
- runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay);
- runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
- runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
-
- now_src_->Advance(delay * 2);
- // After task 2 has run, the automatic selector will have to choose between
- // tasks 1 and 3. The sequence numbers are used to choose between the two
- // tasks and if they are correct task 1 will run last.
- test_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfShorterDelayedTask) {
- Initialize(2u, SelectorType::Automatic);
-
- scoped_refptr<base::SingleThreadTaskRunner> runners[2] = {
- manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)};
-
- std::vector<int> run_order;
-
- base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10);
- base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5);
- runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- delay1);
- runners[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- delay2);
-
- now_src_->Advance(delay1 * 2);
- test_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(run_order, ElementsAre(2, 1));
-}
-
-TEST_F(TaskQueueManagerTest, DelayedTaskWithAbsoluteRunTime) {
- Initialize(1u, SelectorType::Automatic);
-
- scoped_refptr<TaskQueue> runner = manager_->TaskRunnerForQueue(0);
-
- std::vector<int> run_order;
-
- // One task in the past, two with the exact same run time and one in the
- // future.
- base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
- base::TimeTicks runTime1 = now_src_->NowTicks() - delay;
- base::TimeTicks runTime2 = now_src_->NowTicks();
- base::TimeTicks runTime3 = now_src_->NowTicks();
- base::TimeTicks runTime4 = now_src_->NowTicks() + delay;
-
- runner->PostDelayedTaskAt(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
- runTime1);
- runner->PostDelayedTaskAt(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
- runTime2);
- runner->PostDelayedTaskAt(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
- runTime3);
- runner->PostDelayedTaskAt(FROM_HERE, base::Bind(&TestTask, 4, &run_order),
- runTime4);
-
- now_src_->Advance(2 * delay);
- test_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4));
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/child/task_queue_selector.h b/chromium/components/scheduler/child/task_queue_selector.h
deleted file mode 100644
index 2af9e2b62ff..00000000000
--- a/chromium/components/scheduler/child/task_queue_selector.h
+++ /dev/null
@@ -1,56 +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_SCHEDULER_CHILD_TASK_QUEUE_SELECTOR_H_
-#define COMPONENTS_SCHEDULER_CHILD_TASK_QUEUE_SELECTOR_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "components/scheduler/scheduler_export.h"
-
-namespace base {
-class TaskQueue;
-namespace trace_event {
-class TracedValue;
-} // namespace trace_event
-} // namespace base
-
-namespace scheduler {
-
-class TaskQueueSelector {
- public:
- virtual ~TaskQueueSelector() {}
-
- // Called once to register the work queues to be selected from. This function
- // is called on the main thread.
- virtual void RegisterWorkQueues(
- const std::vector<const base::TaskQueue*>& work_queues) = 0;
-
- class SCHEDULER_EXPORT Observer {
- public:
- virtual ~Observer() {}
-
- // Called when a task queue transitions from disabled to enabled.
- virtual void OnTaskQueueEnabled() = 0;
- };
-
- // Called once to set the Observer. This function is called
- // on the main thread. If |observer| is null, then no callbacks will occur.
- virtual void SetTaskQueueSelectorObserver(Observer* observer) = 0;
-
- // Called to choose the work queue from which the next task should be taken
- // and run. Return true if |out_queue| indicates the queue to service or
- // false to avoid running any task.
- //
- // This function is called on the main thread.
- virtual bool SelectWorkQueueToService(size_t* out_queue_index) = 0;
-
- // Serialize the selector state for tracing.
- virtual void AsValueInto(base::trace_event::TracedValue* state) const = 0;
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_CHILD_TASK_QUEUE_SELECTOR_H_
diff --git a/chromium/components/scheduler/child/web_scheduler_impl.cc b/chromium/components/scheduler/child/web_scheduler_impl.cc
index 6b56cc03243..9bf2c0583bf 100644
--- a/chromium/components/scheduler/child/web_scheduler_impl.cc
+++ b/chromium/components/scheduler/child/web_scheduler_impl.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
+#include "components/scheduler/child/web_task_runner_impl.h"
#include "components/scheduler/child/worker_scheduler.h"
#include "third_party/WebKit/public/platform/WebTraceLocation.h"
@@ -18,8 +19,9 @@ WebSchedulerImpl::WebSchedulerImpl(
scoped_refptr<TaskQueue> timer_task_runner)
: child_scheduler_(child_scheduler),
idle_task_runner_(idle_task_runner),
- loading_task_runner_(loading_task_runner),
- timer_task_runner_(timer_task_runner) {}
+ timer_task_runner_(timer_task_runner),
+ loading_web_task_runner_(new WebTaskRunnerImpl(loading_task_runner)),
+ timer_web_task_runner_(new WebTaskRunnerImpl(timer_task_runner)) {}
WebSchedulerImpl::~WebSchedulerImpl() {
}
@@ -41,10 +43,6 @@ void WebSchedulerImpl::runIdleTask(scoped_ptr<blink::WebThread::IdleTask> task,
task->run((deadline - base::TimeTicks()).InSecondsF());
}
-void WebSchedulerImpl::runTask(scoped_ptr<blink::WebThread::Task> task) {
- task->run();
-}
-
void WebSchedulerImpl::postIdleTask(const blink::WebTraceLocation& web_location,
blink::WebThread::IdleTask* task) {
DCHECK(idle_task_runner_);
@@ -80,43 +78,23 @@ void WebSchedulerImpl::postIdleTaskAfterWakeup(
base::Bind(&WebSchedulerImpl::runIdleTask, base::Passed(&scoped_task)));
}
-void WebSchedulerImpl::postLoadingTask(
- const blink::WebTraceLocation& web_location,
- blink::WebThread::Task* task) {
- DCHECK(loading_task_runner_);
- scoped_ptr<blink::WebThread::Task> scoped_task(task);
- tracked_objects::Location location(web_location.functionName(),
- web_location.fileName(), -1, nullptr);
- loading_task_runner_->PostTask(
- location,
- base::Bind(&WebSchedulerImpl::runTask, base::Passed(&scoped_task)));
+blink::WebTaskRunner* WebSchedulerImpl::loadingTaskRunner() {
+ return loading_web_task_runner_.get();
}
-void WebSchedulerImpl::postTimerTask(
- const blink::WebTraceLocation& web_location,
- blink::WebThread::Task* task,
- long long delayMs) {
- DCHECK(timer_task_runner_);
- scoped_ptr<blink::WebThread::Task> scoped_task(task);
- tracked_objects::Location location(web_location.functionName(),
- web_location.fileName(), -1, nullptr);
- timer_task_runner_->PostDelayedTask(
- location,
- base::Bind(&WebSchedulerImpl::runTask, base::Passed(&scoped_task)),
- base::TimeDelta::FromMilliseconds(delayMs));
+blink::WebTaskRunner* WebSchedulerImpl::timerTaskRunner() {
+ return timer_web_task_runner_.get();
}
void WebSchedulerImpl::postTimerTaskAt(
const blink::WebTraceLocation& web_location,
- blink::WebThread::Task* task,
+ blink::WebTaskRunner::Task* task,
double monotonicTime) {
DCHECK(timer_task_runner_);
- scoped_ptr<blink::WebThread::Task> scoped_task(task);
tracked_objects::Location location(web_location.functionName(),
web_location.fileName(), -1, nullptr);
timer_task_runner_->PostDelayedTaskAt(
- location,
- base::Bind(&WebSchedulerImpl::runTask, base::Passed(&scoped_task)),
+ location, base::Bind(&blink::WebTaskRunner::Task::run, base::Owned(task)),
base::TimeTicks() + base::TimeDelta::FromSecondsD(monotonicTime));
}
diff --git a/chromium/components/scheduler/child/web_scheduler_impl.h b/chromium/components/scheduler/child/web_scheduler_impl.h
index 44dcb0f9fca..c937db3b823 100644
--- a/chromium/components/scheduler/child/web_scheduler_impl.h
+++ b/chromium/components/scheduler/child/web_scheduler_impl.h
@@ -21,6 +21,7 @@ namespace scheduler {
class ChildScheduler;
class SingleThreadIdleTaskRunner;
class TaskQueue;
+class WebTaskRunnerImpl;
class SCHEDULER_EXPORT WebSchedulerImpl : public blink::WebScheduler {
public:
@@ -32,35 +33,32 @@ class SCHEDULER_EXPORT WebSchedulerImpl : public blink::WebScheduler {
~WebSchedulerImpl() override;
// blink::WebScheduler implementation:
- virtual void shutdown();
- virtual bool shouldYieldForHighPriorityWork();
- virtual bool canExceedIdleDeadlineIfRequired();
- virtual void postIdleTask(const blink::WebTraceLocation& location,
- blink::WebThread::IdleTask* task);
- virtual void postNonNestableIdleTask(const blink::WebTraceLocation& location,
- blink::WebThread::IdleTask* task);
- virtual void postIdleTaskAfterWakeup(const blink::WebTraceLocation& location,
- blink::WebThread::IdleTask* task);
- virtual void postLoadingTask(const blink::WebTraceLocation& location,
- blink::WebThread::Task* task);
- virtual void postTimerTaskAt(const blink::WebTraceLocation& location,
- blink::WebThread::Task* task,
- double monotonicTime);
+ void shutdown() override;
+ bool shouldYieldForHighPriorityWork() override;
+ bool canExceedIdleDeadlineIfRequired() override;
+ void postIdleTask(const blink::WebTraceLocation& location,
+ blink::WebThread::IdleTask* task) override;
+ void postNonNestableIdleTask(const blink::WebTraceLocation& location,
+ blink::WebThread::IdleTask* task) override;
+ void postIdleTaskAfterWakeup(const blink::WebTraceLocation& location,
+ blink::WebThread::IdleTask* task) override;
+ blink::WebTaskRunner* loadingTaskRunner() override;
+ blink::WebTaskRunner* timerTaskRunner() override;
- // TODO(skyostil): Remove once the Blink side patch lands.
- virtual void postTimerTask(const blink::WebTraceLocation& location,
- blink::WebThread::Task* task,
- long long delayMs);
+ // TODO(alexclarke): Remove when possible.
+ void postTimerTaskAt(const blink::WebTraceLocation& location,
+ blink::WebTaskRunner::Task* task,
+ double monotonicTime) override;
private:
static void runIdleTask(scoped_ptr<blink::WebThread::IdleTask> task,
base::TimeTicks deadline);
- static void runTask(scoped_ptr<blink::WebThread::Task> task);
ChildScheduler* child_scheduler_; // NOT OWNED
scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
- scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
scoped_refptr<TaskQueue> timer_task_runner_;
+ scoped_ptr<WebTaskRunnerImpl> loading_web_task_runner_;
+ scoped_ptr<WebTaskRunnerImpl> timer_web_task_runner_;
};
} // namespace scheduler
diff --git a/chromium/components/scheduler/child/web_task_runner_impl.cc b/chromium/components/scheduler/child/web_task_runner_impl.cc
new file mode 100644
index 00000000000..b4794a4c545
--- /dev/null
+++ b/chromium/components/scheduler/child/web_task_runner_impl.cc
@@ -0,0 +1,39 @@
+// 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/scheduler/child/web_task_runner_impl.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "third_party/WebKit/public/platform/WebTraceLocation.h"
+
+namespace scheduler {
+
+WebTaskRunnerImpl::WebTaskRunnerImpl(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : task_runner_(task_runner) {}
+
+WebTaskRunnerImpl::~WebTaskRunnerImpl() {}
+
+void WebTaskRunnerImpl::postTask(const blink::WebTraceLocation& web_location,
+ blink::WebTaskRunner::Task* task) {
+ tracked_objects::Location location(web_location.functionName(),
+ web_location.fileName(), -1, nullptr);
+ task_runner_->PostTask(location, base::Bind(&blink::WebTaskRunner::Task::run,
+ base::Owned(task)));
+}
+
+void WebTaskRunnerImpl::postDelayedTask(
+ const blink::WebTraceLocation& web_location,
+ blink::WebTaskRunner::Task* task,
+ double delayMs) {
+ tracked_objects::Location location(web_location.functionName(),
+ web_location.fileName(), -1, nullptr);
+ task_runner_->PostDelayedTask(
+ location, base::Bind(&blink::WebTaskRunner::Task::run, base::Owned(task)),
+ base::TimeDelta::FromMillisecondsD(delayMs));
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/child/web_task_runner_impl.h b/chromium/components/scheduler/child/web_task_runner_impl.h
new file mode 100644
index 00000000000..73a1e46fc60
--- /dev/null
+++ b/chromium/components/scheduler/child/web_task_runner_impl.h
@@ -0,0 +1,46 @@
+// 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_SCHEDULER_CHILD_WEB_TASK_RUNNER_H_
+#define COMPONENTS_SCHEDULER_CHILD_WEB_TASK_RUNNER_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/scheduler/scheduler_export.h"
+#include "third_party/WebKit/public/platform/WebTaskRunner.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace scheduler {
+
+class SCHEDULER_EXPORT WebTaskRunnerImpl : public blink::WebTaskRunner {
+ public:
+ explicit WebTaskRunnerImpl(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+ ~WebTaskRunnerImpl() override;
+
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner() const {
+ return task_runner_;
+ }
+
+ // blink::WebTaskRunner implementation:
+ void postTask(const blink::WebTraceLocation& web_location,
+ blink::WebTaskRunner::Task* task) override;
+ void postDelayedTask(const blink::WebTraceLocation& web_location,
+ blink::WebTaskRunner::Task* task,
+ double delayMs) override;
+
+ private:
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebTaskRunnerImpl);
+};
+
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_CHILD_WEB_TASK_RUNNER_H_
diff --git a/chromium/components/scheduler/child/webthread_base.cc b/chromium/components/scheduler/child/webthread_base.cc
index a48849d3540..71c2b3189c5 100644
--- a/chromium/components/scheduler/child/webthread_base.cc
+++ b/chromium/components/scheduler/child/webthread_base.cc
@@ -72,35 +72,6 @@ void WebThreadBase::RemoveTaskObserverInternal(
base::MessageLoop::current()->RemoveTaskObserver(observer);
}
-// RunWebThreadTask takes the ownership of |task| from base::Closure and
-// deletes it on the first invocation of the closure for thread-safety.
-// base::Closure made from RunWebThreadTask is copyable but Closure::Run
-// should be called at most only once.
-// This is because WebThread::Task can contain RefPtr to a
-// thread-unsafe-reference-counted object (e.g. WorkerThreadTask can contain
-// RefPtr to WebKit's StringImpl), and if we don't delete |task| here,
-// it causes a race condition as follows:
-// [A] In task->run(), more RefPtr's to the refcounted object can be created,
-// and the reference counter of the object can be modified via these
-// RefPtr's (as intended) on the thread where the task is executed.
-// [B] However, base::Closure still retains the ownership of WebThread::Task
-// even after RunWebThreadTask is called.
-// When base::Closure is deleted, WebThread::Task is deleted and the
-// reference counter of the object is decreased by one, possibly from a
-// different thread from [A], which is a race condition.
-// Taking the ownership of |task| here by using scoped_ptr and base::Passed
-// removes the reference counter modification of [B] and the race condition.
-// When the closure never runs at all, the corresponding WebThread::Task is
-// destructed when base::Closure is deleted (like [B]). In this case, there
-// are no reference counter modification like [A] (because task->run() is not
-// executed), so there are no race conditions.
-// See https://crbug.com/390851 for more details.
-//
-// static
-void WebThreadBase::RunWebThreadTask(scoped_ptr<blink::WebThread::Task> task) {
- task->run();
-}
-
// static
void WebThreadBase::RunWebThreadIdleTask(
scoped_ptr<blink::WebThread::IdleTask> idle_task,
@@ -108,22 +79,6 @@ void WebThreadBase::RunWebThreadIdleTask(
idle_task->run((deadline - base::TimeTicks()).InSecondsF());
}
-void WebThreadBase::postTask(const blink::WebTraceLocation& location,
- Task* task) {
- postDelayedTask(location, task, 0);
-}
-
-void WebThreadBase::postDelayedTask(const blink::WebTraceLocation& web_location,
- Task* task,
- long long delay_ms) {
- tracked_objects::Location location(web_location.functionName(),
- web_location.fileName(), -1, nullptr);
- TaskRunner()->PostDelayedTask(
- location,
- base::Bind(RunWebThreadTask, base::Passed(make_scoped_ptr(task))),
- base::TimeDelta::FromMilliseconds(delay_ms));
-}
-
void WebThreadBase::postIdleTask(const blink::WebTraceLocation& web_location,
IdleTask* idle_task) {
tracked_objects::Location location(web_location.functionName(),
diff --git a/chromium/components/scheduler/child/webthread_base.h b/chromium/components/scheduler/child/webthread_base.h
index adc92771681..d4f7663cc0d 100644
--- a/chromium/components/scheduler/child/webthread_base.h
+++ b/chromium/components/scheduler/child/webthread_base.h
@@ -21,23 +21,19 @@ class SingleThreadIdleTaskRunner;
class SCHEDULER_EXPORT WebThreadBase : public blink::WebThread {
public:
- virtual ~WebThreadBase();
+ ~WebThreadBase() override;
// blink::WebThread implementation.
- virtual bool isCurrentThread() const;
- virtual blink::PlatformThreadId threadId() const = 0;
+ bool isCurrentThread() const override;
+ blink::PlatformThreadId threadId() const override = 0;
- virtual void postTask(const blink::WebTraceLocation& location, Task* task);
- virtual void postDelayedTask(const blink::WebTraceLocation& location,
- Task* task,
- long long delay_ms);
virtual void postIdleTask(const blink::WebTraceLocation& location,
IdleTask* idle_task);
virtual void postIdleTaskAfterWakeup(const blink::WebTraceLocation& location,
IdleTask* idle_task);
- virtual void addTaskObserver(TaskObserver* observer);
- virtual void removeTaskObserver(TaskObserver* observer);
+ void addTaskObserver(TaskObserver* observer) override;
+ void removeTaskObserver(TaskObserver* observer) override;
// Returns the base::Bind-compatible task runner for posting tasks to this
// thread. Can be called from any thread.
@@ -57,7 +53,6 @@ class SCHEDULER_EXPORT WebThreadBase : public blink::WebThread {
virtual void RemoveTaskObserverInternal(
base::MessageLoop::TaskObserver* observer);
- static void RunWebThreadTask(scoped_ptr<blink::WebThread::Task> task);
static void RunWebThreadIdleTask(
scoped_ptr<blink::WebThread::IdleTask> idle_task,
base::TimeTicks deadline);
diff --git a/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler.cc b/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler.cc
index 87ac8208c74..0706d53efdf 100644
--- a/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler.cc
+++ b/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler.cc
@@ -8,8 +8,10 @@
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
-#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/base/task_queue.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate_impl.h"
#include "components/scheduler/child/web_scheduler_impl.h"
+#include "components/scheduler/child/web_task_runner_impl.h"
#include "components/scheduler/child/worker_scheduler_impl.h"
#include "third_party/WebKit/public/platform/WebTraceLocation.h"
@@ -19,21 +21,31 @@ WebThreadImplForWorkerScheduler::WebThreadImplForWorkerScheduler(
const char* name)
: thread_(new base::Thread(name)) {
thread_->Start();
+ thread_task_runner_ = thread_->task_runner();
base::WaitableEvent completion(false, false);
- thread_->task_runner()->PostTask(
+ thread_task_runner_->PostTask(
FROM_HERE, base::Bind(&WebThreadImplForWorkerScheduler::InitOnThread,
base::Unretained(this), &completion));
completion.Wait();
}
WebThreadImplForWorkerScheduler::~WebThreadImplForWorkerScheduler() {
+ base::WaitableEvent completion(false, false);
+ // Restore the original task runner so that the thread can tear itself down.
+ thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&WebThreadImplForWorkerScheduler::RestoreTaskRunnerOnThread,
+ base::Unretained(this), &completion));
+ completion.Wait();
thread_->Stop();
}
void WebThreadImplForWorkerScheduler::InitOnThread(
base::WaitableEvent* completion) {
- worker_scheduler_ = WorkerScheduler::Create(thread_->message_loop());
+ task_runner_delegate_ =
+ SchedulerTaskRunnerDelegateImpl::Create(thread_->message_loop());
+ worker_scheduler_ = WorkerScheduler::Create(task_runner_delegate_);
worker_scheduler_->Init();
task_runner_ = worker_scheduler_->DefaultTaskRunner();
idle_task_runner_ = worker_scheduler_->IdleTaskRunner();
@@ -42,6 +54,13 @@ void WebThreadImplForWorkerScheduler::InitOnThread(
worker_scheduler_->DefaultTaskRunner(),
worker_scheduler_->DefaultTaskRunner()));
base::MessageLoop::current()->AddDestructionObserver(this);
+ web_task_runner_ = make_scoped_ptr(new WebTaskRunnerImpl(task_runner_));
+ completion->Signal();
+}
+
+void WebThreadImplForWorkerScheduler::RestoreTaskRunnerOnThread(
+ base::WaitableEvent* completion) {
+ task_runner_delegate_->RestoreDefaultTaskRunner();
completion->Signal();
}
@@ -53,7 +72,7 @@ void WebThreadImplForWorkerScheduler::WillDestroyCurrentMessageLoop() {
}
blink::PlatformThreadId WebThreadImplForWorkerScheduler::threadId() const {
- return thread_->thread_id();
+ return thread_->GetThreadId();
}
blink::WebScheduler* WebThreadImplForWorkerScheduler::scheduler() const {
@@ -70,6 +89,10 @@ SingleThreadIdleTaskRunner* WebThreadImplForWorkerScheduler::IdleTaskRunner()
return idle_task_runner_.get();
}
+blink::WebTaskRunner* WebThreadImplForWorkerScheduler::taskRunner() {
+ return web_task_runner_.get();
+}
+
void WebThreadImplForWorkerScheduler::AddTaskObserverInternal(
base::MessageLoop::TaskObserver* observer) {
worker_scheduler_->AddTaskObserver(observer);
diff --git a/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler.h b/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler.h
index 1c0f0ed9200..f6ab21fd0e4 100644
--- a/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler.h
+++ b/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler.h
@@ -5,7 +5,7 @@
#ifndef COMPONENTS_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_
#define COMPONENTS_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_
-#include "components/scheduler/child/task_queue_manager.h"
+#include "components/scheduler/base/task_queue_manager.h"
#include "components/scheduler/child/webthread_base.h"
namespace base {
@@ -17,8 +17,10 @@ class WebScheduler;
};
namespace scheduler {
+class SchedulerTaskRunnerDelegate;
class SingleThreadIdleTaskRunner;
class WebSchedulerImpl;
+class WebTaskRunnerImpl;
class WorkerScheduler;
class SCHEDULER_EXPORT WebThreadImplForWorkerScheduler
@@ -26,11 +28,12 @@ class SCHEDULER_EXPORT WebThreadImplForWorkerScheduler
public base::MessageLoop::DestructionObserver {
public:
explicit WebThreadImplForWorkerScheduler(const char* name);
- virtual ~WebThreadImplForWorkerScheduler();
+ ~WebThreadImplForWorkerScheduler() override;
// blink::WebThread implementation.
- virtual blink::WebScheduler* scheduler() const;
+ blink::WebScheduler* scheduler() const override;
blink::PlatformThreadId threadId() const override;
+ blink::WebTaskRunner* taskRunner() override;
// WebThreadBase implementation.
base::SingleThreadTaskRunner* TaskRunner() const override;
@@ -46,12 +49,16 @@ class SCHEDULER_EXPORT WebThreadImplForWorkerScheduler
base::MessageLoop::TaskObserver* observer) override;
void InitOnThread(base::WaitableEvent* completion);
+ void RestoreTaskRunnerOnThread(base::WaitableEvent* completion);
scoped_ptr<base::Thread> thread_;
scoped_ptr<scheduler::WorkerScheduler> worker_scheduler_;
scoped_ptr<scheduler::WebSchedulerImpl> web_scheduler_;
+ scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
scoped_refptr<scheduler::SingleThreadIdleTaskRunner> idle_task_runner_;
+ scoped_refptr<SchedulerTaskRunnerDelegate> task_runner_delegate_;
+ scoped_ptr<WebTaskRunnerImpl> web_task_runner_;
};
} // namespace scheduler
diff --git a/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc b/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
index 40013a11d1a..1f79c5c6884 100644
--- a/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
+++ b/chromium/components/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
@@ -19,14 +19,14 @@ using testing::Invoke;
namespace scheduler {
namespace {
-class NopTask : public blink::WebThread::Task {
+class NopTask : public blink::WebTaskRunner::Task {
public:
~NopTask() override {}
- void run() {}
+ void run() override {}
};
-class MockTask : public blink::WebThread::Task {
+class MockTask : public blink::WebTaskRunner::Task {
public:
~MockTask() override {}
@@ -54,7 +54,7 @@ class TestObserver : public blink::WebThread::TaskObserver {
std::string* calls_; // NOT OWNED
};
-class TestTask : public blink::WebThread::Task {
+class TestTask : public blink::WebTaskRunner::Task {
public:
explicit TestTask(std::string* calls) : calls_(calls) {}
@@ -124,7 +124,7 @@ TEST_F(WebThreadImplForWorkerSchedulerTest, TestDefaultTask) {
ON_CALL(*task, run())
.WillByDefault(Invoke([&completion]() { completion.Signal(); }));
- thread_->postTask(blink::WebTraceLocation(), task.release());
+ thread_->taskRunner()->postTask(blink::WebTraceLocation(), task.release());
completion.Wait();
}
@@ -137,7 +137,7 @@ TEST_F(WebThreadImplForWorkerSchedulerTest,
ON_CALL(*task, run())
.WillByDefault(Invoke([&completion]() { completion.Signal(); }));
- thread_->postTask(blink::WebTraceLocation(), task.release());
+ thread_->taskRunner()->postTask(blink::WebTraceLocation(), task.release());
thread_.reset();
}
@@ -151,7 +151,8 @@ TEST_F(WebThreadImplForWorkerSchedulerTest, TestIdleTask) {
thread_->postIdleTask(blink::WebTraceLocation(), task.release());
// We need to post a wakeup task or idle work will never happen.
- thread_->postDelayedTask(blink::WebTraceLocation(), new NopTask(), 50ul);
+ thread_->taskRunner()->postDelayedTask(blink::WebTraceLocation(),
+ new NopTask(), 50ll);
completion.Wait();
}
@@ -162,7 +163,8 @@ TEST_F(WebThreadImplForWorkerSchedulerTest, TestTaskObserver) {
RunOnWorkerThread(FROM_HERE,
base::Bind(&addTaskObserver, thread_.get(), &observer));
- thread_->postTask(blink::WebTraceLocation(), new TestTask(&calls));
+ thread_->taskRunner()->postTask(blink::WebTraceLocation(),
+ new TestTask(&calls));
RunOnWorkerThread(FROM_HERE,
base::Bind(&removeTaskObserver, thread_.get(), &observer));
@@ -182,8 +184,9 @@ TEST_F(WebThreadImplForWorkerSchedulerTest, TestShutdown) {
EXPECT_CALL(*delayed_task, run()).Times(0);
RunOnWorkerThread(FROM_HERE, base::Bind(&shutdownOnThread, thread_.get()));
- thread_->postTask(blink::WebTraceLocation(), task.release());
- thread_->postDelayedTask(blink::WebTraceLocation(), task.release(), 50ul);
+ thread_->taskRunner()->postTask(blink::WebTraceLocation(), task.release());
+ thread_->taskRunner()->postDelayedTask(blink::WebTraceLocation(),
+ task.release(), 50ll);
thread_.reset();
}
diff --git a/chromium/components/scheduler/child/worker_scheduler.cc b/chromium/components/scheduler/child/worker_scheduler.cc
index a1ddc988105..55db90dcdd8 100644
--- a/chromium/components/scheduler/child/worker_scheduler.cc
+++ b/chromium/components/scheduler/child/worker_scheduler.cc
@@ -4,12 +4,9 @@
#include "components/scheduler/child/worker_scheduler.h"
-#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
-#include "components/scheduler/child/null_worker_scheduler.h"
-#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate.h"
#include "components/scheduler/child/worker_scheduler_impl.h"
-#include "components/scheduler/common/scheduler_switches.h"
namespace scheduler {
@@ -21,14 +18,8 @@ WorkerScheduler::~WorkerScheduler() {
// static
scoped_ptr<WorkerScheduler> WorkerScheduler::Create(
- base::MessageLoop* message_loop) {
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kDisableBlinkScheduler)) {
- return make_scoped_ptr(new NullWorkerScheduler());
- } else {
- return make_scoped_ptr(new WorkerSchedulerImpl(
- SchedulerMessageLoopDelegate::Create(message_loop)));
- }
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner) {
+ return make_scoped_ptr(new WorkerSchedulerImpl(main_task_runner.Pass()));
}
} // namespace scheduler
diff --git a/chromium/components/scheduler/child/worker_scheduler.h b/chromium/components/scheduler/child/worker_scheduler.h
index 333821094e3..7a1ec046310 100644
--- a/chromium/components/scheduler/child/worker_scheduler.h
+++ b/chromium/components/scheduler/child/worker_scheduler.h
@@ -15,11 +15,13 @@ class MessageLoop;
}
namespace scheduler {
+class SchedulerTaskRunnerDelegate;
class SCHEDULER_EXPORT WorkerScheduler : public ChildScheduler {
public:
~WorkerScheduler() override;
- static scoped_ptr<WorkerScheduler> Create(base::MessageLoop* message_loop);
+ static scoped_ptr<WorkerScheduler> Create(
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner);
// Must be called before the scheduler can be used. Does any post construction
// initialization needed such as initializing idle period detection.
diff --git a/chromium/components/scheduler/child/worker_scheduler_impl.cc b/chromium/components/scheduler/child/worker_scheduler_impl.cc
index 21774d5aa47..673d4474e50 100644
--- a/chromium/components/scheduler/child/worker_scheduler_impl.cc
+++ b/chromium/components/scheduler/child/worker_scheduler_impl.cc
@@ -7,20 +7,19 @@
#include "base/bind.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
-#include "components/scheduler/child/nestable_single_thread_task_runner.h"
+#include "components/scheduler/base/task_queue.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate.h"
namespace scheduler {
WorkerSchedulerImpl::WorkerSchedulerImpl(
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner)
: helper_(main_task_runner,
"worker.scheduler",
TRACE_DISABLED_BY_DEFAULT("worker.scheduler"),
- TRACE_DISABLED_BY_DEFAULT("worker.scheduler.debug"),
- TASK_QUEUE_COUNT),
+ TRACE_DISABLED_BY_DEFAULT("worker.scheduler.debug")),
idle_helper_(&helper_,
this,
- IDLE_TASK_QUEUE,
"worker.scheduler",
TRACE_DISABLED_BY_DEFAULT("worker.scheduler"),
"WorkerSchedulerIdlePeriod",
diff --git a/chromium/components/scheduler/child/worker_scheduler_impl.h b/chromium/components/scheduler/child/worker_scheduler_impl.h
index 24b044c8c0b..65fee33908d 100644
--- a/chromium/components/scheduler/child/worker_scheduler_impl.h
+++ b/chromium/components/scheduler/child/worker_scheduler_impl.h
@@ -18,13 +18,13 @@ class ConvertableToTraceFormat;
namespace scheduler {
-class NestableSingleThreadTaskRunner;
+class SchedulerTaskRunnerDelegate;
class SCHEDULER_EXPORT WorkerSchedulerImpl : public WorkerScheduler,
public IdleHelper::Delegate {
public:
explicit WorkerSchedulerImpl(
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner);
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner);
~WorkerSchedulerImpl() override;
// WorkerScheduler implementation:
@@ -51,12 +51,6 @@ class SCHEDULER_EXPORT WorkerSchedulerImpl : public WorkerScheduler,
void OnIdlePeriodEnded() override {}
private:
- enum QueueId {
- IDLE_TASK_QUEUE = SchedulerHelper::TASK_QUEUE_COUNT,
- // Must be the last entry.
- TASK_QUEUE_COUNT,
- };
-
void MaybeStartLongIdlePeriod();
SchedulerHelper helper_;
diff --git a/chromium/components/scheduler/child/worker_scheduler_impl_unittest.cc b/chromium/components/scheduler/child/worker_scheduler_impl_unittest.cc
index 451d86197ce..47e0c68c801 100644
--- a/chromium/components/scheduler/child/worker_scheduler_impl_unittest.cc
+++ b/chromium/components/scheduler/child/worker_scheduler_impl_unittest.cc
@@ -8,9 +8,8 @@
#include "base/strings/stringprintf.h"
#include "base/test/simple_test_tick_clock.h"
#include "cc/test/ordered_simple_task_runner.h"
-#include "components/scheduler/child/nestable_task_runner_for_test.h"
-#include "components/scheduler/child/scheduler_message_loop_delegate.h"
-#include "components/scheduler/child/test_time_source.h"
+#include "components/scheduler/base/test_time_source.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate_for_test.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -54,7 +53,7 @@ void TimelineIdleTestTask(std::vector<std::string>* timeline,
class WorkerSchedulerImplForTest : public WorkerSchedulerImpl {
public:
WorkerSchedulerImplForTest(
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner,
base::SimpleTestTickClock* clock_)
: WorkerSchedulerImpl(main_task_runner),
clock_(clock_),
@@ -93,10 +92,10 @@ class WorkerSchedulerImplTest : public testing::Test {
WorkerSchedulerImplTest()
: clock_(new base::SimpleTestTickClock()),
mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_.get(), true)),
- nestable_task_runner_(
- NestableTaskRunnerForTest::Create(mock_task_runner_)),
- scheduler_(new WorkerSchedulerImplForTest(nestable_task_runner_,
- clock_.get())),
+ main_task_runner_(
+ SchedulerTaskRunnerDelegateForTest::Create(mock_task_runner_)),
+ scheduler_(
+ new WorkerSchedulerImplForTest(main_task_runner_, clock_.get())),
timeline_(nullptr) {
clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
scheduler_->GetSchedulerHelperForTesting()->SetTimeSourceForTesting(
@@ -176,7 +175,7 @@ class WorkerSchedulerImplTest : public testing::Test {
// Only one of mock_task_runner_ or message_loop_ will be set.
scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
- scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner_;
scoped_ptr<WorkerSchedulerImplForTest> scheduler_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
diff --git a/chromium/components/scheduler/common/scheduler_switches.cc b/chromium/components/scheduler/common/scheduler_switches.cc
deleted file mode 100644
index 7d7eca64a8f..00000000000
--- a/chromium/components/scheduler/common/scheduler_switches.cc
+++ /dev/null
@@ -1,15 +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/scheduler/common/scheduler_switches.h"
-
-namespace scheduler {
-namespace switches {
-
-// Disable the Blink Scheduler. Ensures there's no reordering of blink tasks.
-// This switch is intended only for performance tests.
-const char kDisableBlinkScheduler[] = "disable-blink-scheduler";
-
-} // namespace switches
-} // namespace scheduler
diff --git a/chromium/components/scheduler/common/scheduler_switches.h b/chromium/components/scheduler/common/scheduler_switches.h
deleted file mode 100644
index 8d909d9e0d6..00000000000
--- a/chromium/components/scheduler/common/scheduler_switches.h
+++ /dev/null
@@ -1,16 +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_SCHEDULER_COMMON_SCHEDULER_SWITCHES_H_
-#define COMPONENTS_SCHEDULER_COMMON_SCHEDULER_SWITCHES_H_
-
-namespace scheduler {
-namespace switches {
-
-extern const char kDisableBlinkScheduler[];
-
-} // namespace switches
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_COMMON_SCHEDULER_SWITCHES_H_
diff --git a/chromium/components/scheduler/ppapi/DEPS b/chromium/components/scheduler/ppapi/DEPS
new file mode 100644
index 00000000000..ed66f914172
--- /dev/null
+++ b/chromium/components/scheduler/ppapi/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "+components/scheduler/base",
+ "+components/scheduler/child",
+ "+components/scheduler/scheduler_export.h",
+ "+third_party/WebKit/public/platform",
+]
diff --git a/chromium/components/scheduler/ppapi/webthread_impl_for_ppapi.cc b/chromium/components/scheduler/ppapi/webthread_impl_for_ppapi.cc
new file mode 100644
index 00000000000..113efdc4da6
--- /dev/null
+++ b/chromium/components/scheduler/ppapi/webthread_impl_for_ppapi.cc
@@ -0,0 +1,65 @@
+// 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/scheduler/ppapi/webthread_impl_for_ppapi.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "components/scheduler/base/task_queue.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate_impl.h"
+#include "components/scheduler/child/web_scheduler_impl.h"
+#include "components/scheduler/child/web_task_runner_impl.h"
+#include "components/scheduler/child/worker_scheduler_impl.h"
+
+namespace scheduler {
+
+WebThreadImplForPPAPI::WebThreadImplForPPAPI()
+ : thread_id_(base::PlatformThread::CurrentId()),
+ task_runner_delegate_(SchedulerTaskRunnerDelegateImpl::Create(
+ base::MessageLoop::current())),
+ worker_scheduler_(WorkerScheduler::Create(task_runner_delegate_)) {
+ worker_scheduler_->Init();
+ task_runner_ = worker_scheduler_->DefaultTaskRunner();
+ idle_task_runner_ = worker_scheduler_->IdleTaskRunner();
+ web_scheduler_.reset(new WebSchedulerImpl(
+ worker_scheduler_.get(), worker_scheduler_->IdleTaskRunner(),
+ worker_scheduler_->DefaultTaskRunner(),
+ worker_scheduler_->DefaultTaskRunner()));
+ web_task_runner_ = make_scoped_ptr(new WebTaskRunnerImpl(task_runner_));
+}
+
+WebThreadImplForPPAPI::~WebThreadImplForPPAPI() {}
+
+blink::PlatformThreadId WebThreadImplForPPAPI::threadId() const {
+ return thread_id_;
+}
+
+blink::WebScheduler* WebThreadImplForPPAPI::scheduler() const {
+ return web_scheduler_.get();
+}
+
+base::SingleThreadTaskRunner* WebThreadImplForPPAPI::TaskRunner() const {
+ return task_runner_.get();
+}
+
+SingleThreadIdleTaskRunner* WebThreadImplForPPAPI::IdleTaskRunner() const {
+ return idle_task_runner_.get();
+}
+
+blink::WebTaskRunner* WebThreadImplForPPAPI::taskRunner() {
+ return web_task_runner_.get();
+}
+
+void WebThreadImplForPPAPI::AddTaskObserverInternal(
+ base::MessageLoop::TaskObserver* observer) {
+ worker_scheduler_->AddTaskObserver(observer);
+}
+
+void WebThreadImplForPPAPI::RemoveTaskObserverInternal(
+ base::MessageLoop::TaskObserver* observer) {
+ worker_scheduler_->RemoveTaskObserver(observer);
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/ppapi/webthread_impl_for_ppapi.h b/chromium/components/scheduler/ppapi/webthread_impl_for_ppapi.h
new file mode 100644
index 00000000000..d85c02ae0ba
--- /dev/null
+++ b/chromium/components/scheduler/ppapi/webthread_impl_for_ppapi.h
@@ -0,0 +1,57 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SCHEDULER_PPAPI_WEBTHREAD_IMPL_FOR_PPAPI_H_
+#define COMPONENTS_SCHEDULER_PPAPI_WEBTHREAD_IMPL_FOR_PPAPI_H_
+
+#include "components/scheduler/child/webthread_base.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace blink {
+class WebScheduler;
+};
+
+namespace scheduler {
+class SchedulerTaskRunnerDelegate;
+class SingleThreadIdleTaskRunner;
+class WebSchedulerImpl;
+class WebTaskRunnerImpl;
+class WorkerScheduler;
+
+class SCHEDULER_EXPORT WebThreadImplForPPAPI : public WebThreadBase {
+ public:
+ explicit WebThreadImplForPPAPI();
+ virtual ~WebThreadImplForPPAPI();
+
+ // blink::WebThread implementation.
+ virtual blink::WebScheduler* scheduler() const;
+ blink::PlatformThreadId threadId() const override;
+ virtual blink::WebTaskRunner* taskRunner();
+
+ // WebThreadBase implementation.
+ base::SingleThreadTaskRunner* TaskRunner() const override;
+ scheduler::SingleThreadIdleTaskRunner* IdleTaskRunner() const override;
+
+ private:
+ void AddTaskObserverInternal(
+ base::MessageLoop::TaskObserver* observer) override;
+ void RemoveTaskObserverInternal(
+ base::MessageLoop::TaskObserver* observer) override;
+
+ blink::PlatformThreadId thread_id_;
+ scoped_refptr<SchedulerTaskRunnerDelegate> task_runner_delegate_;
+ scoped_ptr<scheduler::WorkerScheduler> worker_scheduler_;
+ scoped_ptr<scheduler::WebSchedulerImpl> web_scheduler_;
+ scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ scoped_refptr<scheduler::SingleThreadIdleTaskRunner> idle_task_runner_;
+ scoped_ptr<WebTaskRunnerImpl> web_task_runner_;
+};
+
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_PPAPI_WEBTHREAD_IMPL_FOR_PPAPI_H_
diff --git a/chromium/components/scheduler/renderer/DEPS b/chromium/components/scheduler/renderer/DEPS
index 3425c1a9e30..2f3b2d4dbfc 100644
--- a/chromium/components/scheduler/renderer/DEPS
+++ b/chromium/components/scheduler/renderer/DEPS
@@ -1,7 +1,8 @@
include_rules = [
+ "+components/scheduler/base",
"+components/scheduler/child",
- "+components/scheduler/common",
"+components/scheduler/scheduler_export.h",
+ "+cc/base",
"+cc/output",
"+ui/gfx",
"+third_party/WebKit/public/platform",
diff --git a/chromium/components/scheduler/renderer/deadline_task_runner.h b/chromium/components/scheduler/renderer/deadline_task_runner.h
index 7988cc4eb98..9ac4823277b 100644
--- a/chromium/components/scheduler/renderer/deadline_task_runner.h
+++ b/chromium/components/scheduler/renderer/deadline_task_runner.h
@@ -10,7 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
-#include "components/scheduler/child/cancelable_closure_holder.h"
+#include "components/scheduler/base/cancelable_closure_holder.h"
#include "components/scheduler/scheduler_export.h"
namespace scheduler {
diff --git a/chromium/components/scheduler/renderer/null_renderer_scheduler.cc b/chromium/components/scheduler/renderer/null_renderer_scheduler.cc
deleted file mode 100644
index 11b577fc636..00000000000
--- a/chromium/components/scheduler/renderer/null_renderer_scheduler.cc
+++ /dev/null
@@ -1,106 +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/scheduler/renderer/null_renderer_scheduler.h"
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/thread_task_runner_handle.h"
-#include "components/scheduler/child/null_idle_task_runner.h"
-#include "components/scheduler/child/null_task_queue.h"
-
-namespace scheduler {
-
-NullRendererScheduler::NullRendererScheduler()
- : task_runner_(new NullTaskQueue(base::ThreadTaskRunnerHandle::Get())),
- idle_task_runner_(new NullIdleTaskRunner()) {}
-
-NullRendererScheduler::~NullRendererScheduler() {
-}
-
-scoped_refptr<TaskQueue> NullRendererScheduler::DefaultTaskRunner() {
- return task_runner_;
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-NullRendererScheduler::CompositorTaskRunner() {
- return task_runner_;
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-NullRendererScheduler::LoadingTaskRunner() {
- return task_runner_;
-}
-
-scoped_refptr<SingleThreadIdleTaskRunner>
-NullRendererScheduler::IdleTaskRunner() {
- return idle_task_runner_;
-}
-
-scoped_refptr<TaskQueue> NullRendererScheduler::TimerTaskRunner() {
- return task_runner_;
-}
-
-void NullRendererScheduler::WillBeginFrame(const cc::BeginFrameArgs& args) {
-}
-
-void NullRendererScheduler::BeginFrameNotExpectedSoon() {
-}
-
-void NullRendererScheduler::DidCommitFrameToCompositor() {
-}
-
-void NullRendererScheduler::DidHandleInputEventOnCompositorThread(
- const blink::WebInputEvent& web_input_event,
- InputEventState event_state) {
-}
-
-void NullRendererScheduler::DidHandleInputEventOnMainThread(
- const blink::WebInputEvent& web_input_event) {
-}
-
-void NullRendererScheduler::DidAnimateForInputOnCompositorThread() {
-}
-
-void NullRendererScheduler::OnRendererHidden() {
-}
-
-void NullRendererScheduler::OnRendererVisible() {
-}
-
-void NullRendererScheduler::OnPageLoadStarted() {
-}
-
-bool NullRendererScheduler::IsHighPriorityWorkAnticipated() {
- return false;
-}
-
-bool NullRendererScheduler::ShouldYieldForHighPriorityWork() {
- return false;
-}
-
-bool NullRendererScheduler::CanExceedIdleDeadlineIfRequired() const {
- return false;
-}
-
-void NullRendererScheduler::AddTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- base::MessageLoop::current()->AddTaskObserver(task_observer);
-}
-
-void NullRendererScheduler::RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) {
- base::MessageLoop::current()->RemoveTaskObserver(task_observer);
-}
-
-void NullRendererScheduler::Shutdown() {
-}
-
-void NullRendererScheduler::SuspendTimerQueue() {
-}
-
-void NullRendererScheduler::ResumeTimerQueue() {
-}
-
-} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/null_renderer_scheduler.h b/chromium/components/scheduler/renderer/null_renderer_scheduler.h
deleted file mode 100644
index b989e07180e..00000000000
--- a/chromium/components/scheduler/renderer/null_renderer_scheduler.h
+++ /dev/null
@@ -1,55 +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_SCHEDULER_RENDERER_NULL_RENDERER_SCHEDULER_H_
-#define COMPONENTS_SCHEDULER_RENDERER_NULL_RENDERER_SCHEDULER_H_
-
-#include "components/scheduler/renderer/renderer_scheduler.h"
-
-namespace scheduler {
-class NullTaskQueue;
-
-class NullRendererScheduler : public RendererScheduler {
- public:
- NullRendererScheduler();
- ~NullRendererScheduler() override;
-
- scoped_refptr<TaskQueue> DefaultTaskRunner() override;
- scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override;
- scoped_refptr<base::SingleThreadTaskRunner> LoadingTaskRunner() override;
- scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override;
- scoped_refptr<TaskQueue> TimerTaskRunner() override;
-
- void WillBeginFrame(const cc::BeginFrameArgs& args) override;
- void BeginFrameNotExpectedSoon() override;
- void DidCommitFrameToCompositor() override;
- void DidHandleInputEventOnCompositorThread(
- const blink::WebInputEvent& web_input_event,
- InputEventState event_state) override;
- void DidHandleInputEventOnMainThread(
- const blink::WebInputEvent& web_input_event) override;
- void OnRendererHidden() override;
- void OnRendererVisible() override;
- void OnPageLoadStarted() override;
- void DidAnimateForInputOnCompositorThread() override;
- bool IsHighPriorityWorkAnticipated() override;
- bool ShouldYieldForHighPriorityWork() override;
- bool CanExceedIdleDeadlineIfRequired() const override;
- void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
- void RemoveTaskObserver(
- base::MessageLoop::TaskObserver* task_observer) override;
- void Shutdown() override;
- void SuspendTimerQueue() override;
- void ResumeTimerQueue() override;
-
- private:
- scoped_refptr<NullTaskQueue> task_runner_;
- scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(NullRendererScheduler);
-};
-
-} // namespace scheduler
-
-#endif // COMPONENTS_SCHEDULER_RENDERER_NULL_RENDERER_SCHEDULER_H_
diff --git a/chromium/components/scheduler/renderer/renderer_scheduler.cc b/chromium/components/scheduler/renderer/renderer_scheduler.cc
index 914b8025cc1..20d663437a9 100644
--- a/chromium/components/scheduler/renderer/renderer_scheduler.cc
+++ b/chromium/components/scheduler/renderer/renderer_scheduler.cc
@@ -4,13 +4,10 @@
#include "components/scheduler/renderer/renderer_scheduler.h"
-#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_impl.h"
-#include "components/scheduler/child/scheduler_message_loop_delegate.h"
-#include "components/scheduler/common/scheduler_switches.h"
-#include "components/scheduler/renderer/null_renderer_scheduler.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate_impl.h"
#include "components/scheduler/renderer/renderer_scheduler_impl.h"
namespace scheduler {
@@ -32,13 +29,41 @@ scoped_ptr<RendererScheduler> RendererScheduler::Create() {
base::trace_event::TraceLog::GetCategoryGroupEnabled(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug"));
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kDisableBlinkScheduler)) {
- return make_scoped_ptr(new NullRendererScheduler());
- } else {
- base::MessageLoop* message_loop = base::MessageLoop::current();
- return make_scoped_ptr(new RendererSchedulerImpl(
- SchedulerMessageLoopDelegate::Create(message_loop)));
+ base::MessageLoop* message_loop = base::MessageLoop::current();
+ return make_scoped_ptr(new RendererSchedulerImpl(
+ SchedulerTaskRunnerDelegateImpl::Create(message_loop)));
+}
+
+// static
+const char* RendererScheduler::UseCaseToString(UseCase use_case) {
+ switch (use_case) {
+ case UseCase::NONE:
+ return "none";
+ case UseCase::COMPOSITOR_GESTURE:
+ return "compositor_gesture";
+ case UseCase::MAIN_THREAD_GESTURE:
+ return "main_thread_gesture";
+ case UseCase::TOUCHSTART:
+ return "touchstart";
+ case UseCase::LOADING:
+ return "loading";
+ default:
+ NOTREACHED();
+ return nullptr;
+ }
+}
+
+// static
+const char* RendererScheduler::InputEventStateToString(
+ InputEventState input_event_state) {
+ switch (input_event_state) {
+ case InputEventState::EVENT_CONSUMED_BY_COMPOSITOR:
+ return "event_consumed_by_compositor";
+ case InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD:
+ return "event_forwarded_to_main_thread";
+ default:
+ NOTREACHED();
+ return nullptr;
}
}
diff --git a/chromium/components/scheduler/renderer/renderer_scheduler.h b/chromium/components/scheduler/renderer/renderer_scheduler.h
index c5955b53182..f183b0707e7 100644
--- a/chromium/components/scheduler/renderer/renderer_scheduler.h
+++ b/chromium/components/scheduler/renderer/renderer_scheduler.h
@@ -26,13 +26,34 @@ class SCHEDULER_EXPORT RendererScheduler : public ChildScheduler {
virtual scoped_refptr<base::SingleThreadTaskRunner>
CompositorTaskRunner() = 0;
+ // Keep RendererScheduler::UseCaseToString in sync with this enum.
+ enum class UseCase {
+ NONE,
+ COMPOSITOR_GESTURE,
+ MAIN_THREAD_GESTURE,
+ TOUCHSTART,
+ LOADING,
+ // Must be the last entry.
+ USE_CASE_COUNT,
+ FIRST_USE_CASE = NONE,
+ };
+ static const char* UseCaseToString(UseCase use_case);
+
// Returns the loading task runner. This queue is intended for tasks related
// to resource dispatch, foreground HTML parsing, etc...
virtual scoped_refptr<base::SingleThreadTaskRunner> LoadingTaskRunner() = 0;
// Returns the timer task runner. This queue is intended for DOM Timers.
+ // TODO(alexclarke): Get rid of this default timer queue.
virtual scoped_refptr<TaskQueue> TimerTaskRunner() = 0;
+ // Returns a new loading task runner. This queue is intended for tasks related
+ // to resource dispatch, foreground HTML parsing, etc...
+ virtual scoped_refptr<TaskQueue> NewLoadingTaskRunner(const char* name) = 0;
+
+ // Returns a new timer task runner. This queue is intended for DOM Timers.
+ virtual scoped_refptr<TaskQueue> NewTimerTaskRunner(const char* name) = 0;
+
// Called to notify about the start of an extended period where no frames
// need to be drawn. Must be called from the main thread.
virtual void BeginFrameNotExpectedSoon() = 0;
@@ -45,10 +66,12 @@ class SCHEDULER_EXPORT RendererScheduler : public ChildScheduler {
// called from the main thread.
virtual void DidCommitFrameToCompositor() = 0;
+ // Keep RendererScheduler::InputEventStateToString in sync with this enum.
enum class InputEventState {
EVENT_CONSUMED_BY_COMPOSITOR,
EVENT_FORWARDED_TO_MAIN_THREAD,
};
+ static const char* InputEventStateToString(InputEventState input_event_state);
// Tells the scheduler that the system processed an input event. Called by the
// compositor (impl) thread. Note it's expected that every call to
@@ -79,10 +102,31 @@ class SCHEDULER_EXPORT RendererScheduler : public ChildScheduler {
// Must be called on the main thread.
virtual void OnRendererVisible() = 0;
- // Tells the scheduler that a page load has started. The scheduler will
+ // Tells the scheduler that the renderer process has been backgrounded, i.e.,
+ // there are no critical, user facing activities (visual, audio, etc...)
+ // driven by this process. A stricter condition than |OnRendererHidden()|, the
+ // process is assumed to be foregrounded when the scheduler is constructed.
+ // Must be called on the main thread.
+ virtual void OnRendererBackgrounded() = 0;
+
+ // Tells the scheduler that the renderer process has been foregrounded.
+ // This is the assumed state when the scheduler is constructed.
+ // Must be called on the main thread.
+ virtual void OnRendererForegrounded() = 0;
+
+ // Tells the scheduler that a navigation task is pending. While any navigation
+ // tasks are pending, the scheduler will ensure that loading tasks are not
+ // blocked even if they are expensive. Must be called on the main thread.
+ virtual void AddPendingNavigation() = 0;
+
+ // Tells the scheduler that a navigation task is no longer pending.
+ // Must be called on the main thread.
+ virtual void RemovePendingNavigation() = 0;
+
+ // Tells the scheduler that a navigation has started. The scheduler will
// prioritize loading tasks for a short duration afterwards.
// Must be called from the main thread.
- virtual void OnPageLoadStarted() = 0;
+ virtual void OnNavigationStarted() = 0;
// Returns true if the scheduler has reason to believe that high priority work
// may soon arrive on the main thread, e.g., if gesture events were observed
@@ -98,6 +142,10 @@ class SCHEDULER_EXPORT RendererScheduler : public ChildScheduler {
// if the suspension count is zero and the current schduler policy allows it.
virtual void ResumeTimerQueue() = 0;
+ // Sets whether to allow suspension of timers after the backgrounded signal is
+ // received via OnRendererBackgrounded. Defaults to disabled.
+ virtual void SetTimerQueueSuspensionWhenBackgroundedEnabled(bool enabled) = 0;
+
protected:
RendererScheduler();
DISALLOW_COPY_AND_ASSIGN(RendererScheduler);
diff --git a/chromium/components/scheduler/renderer/renderer_scheduler_impl.cc b/chromium/components/scheduler/renderer/renderer_scheduler_impl.cc
index a885387b194..1193339bddd 100644
--- a/chromium/components/scheduler/renderer/renderer_scheduler_impl.cc
+++ b/chromium/components/scheduler/renderer/renderer_scheduler_impl.cc
@@ -9,31 +9,36 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
#include "cc/output/begin_frame_args.h"
-#include "components/scheduler/child/nestable_single_thread_task_runner.h"
-#include "components/scheduler/child/prioritizing_task_queue_selector.h"
-#include "components/scheduler/child/task_queue.h"
+#include "components/scheduler/base/task_queue_impl.h"
+#include "components/scheduler/base/task_queue_selector.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate.h"
namespace scheduler {
+namespace {
+const int kLoadingTaskEstimationSampleCount = 200;
+const double kLoadingTaskEstimationPercentile = 90;
+const int kTimerTaskEstimationSampleCount = 200;
+const double kTimerTaskEstimationPercentile = 90;
+const int kShortIdlePeriodDurationSampleCount = 10;
+const double kShortIdlePeriodDurationPercentile = 20;
+}
RendererSchedulerImpl::RendererSchedulerImpl(
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner)
: helper_(main_task_runner,
"renderer.scheduler",
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
- TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug"),
- TASK_QUEUE_COUNT),
+ TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")),
idle_helper_(&helper_,
this,
- IDLE_TASK_QUEUE,
"renderer.scheduler",
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
"RendererSchedulerIdlePeriod",
base::TimeDelta()),
control_task_runner_(helper_.ControlTaskRunner()),
compositor_task_runner_(
- helper_.TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)),
- loading_task_runner_(helper_.TaskRunnerForQueue(LOADING_TASK_QUEUE)),
- timer_task_runner_(helper_.TaskRunnerForQueue(TIMER_TASK_QUEUE)),
+ helper_.NewTaskQueue(TaskQueue::Spec("compositor_tq")
+ .SetShouldMonitorQuiescence(true))),
delayed_update_policy_runner_(
base::Bind(&RendererSchedulerImpl::UpdatePolicy,
base::Unretained(this)),
@@ -45,49 +50,85 @@ RendererSchedulerImpl::RendererSchedulerImpl(
end_renderer_hidden_idle_period_closure_.Reset(base::Bind(
&RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr()));
- for (size_t i = SchedulerHelper::TASK_QUEUE_COUNT; i < TASK_QUEUE_COUNT;
- i++) {
- helper_.SetQueueName(i, TaskQueueIdToString(static_cast<QueueId>(i)));
- }
+ suspend_timers_when_backgrounded_closure_.Reset(
+ base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded,
+ weak_factory_.GetWeakPtr()));
+
+ default_loading_task_runner_ = NewLoadingTaskRunner("default_loading_tq");
+ default_timer_task_runner_ = NewTimerTaskRunner("default_timer_tq");
+
TRACE_EVENT_OBJECT_CREATED_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
this);
+
+ // Make sure that we don't initially assume there is no idle time.
+ MainThreadOnly().short_idle_period_duration.InsertSample(
+ cc::BeginFrameArgs::DefaultInterval());
+
+ helper_.SetObserver(this);
}
RendererSchedulerImpl::~RendererSchedulerImpl() {
TRACE_EVENT_OBJECT_DELETED_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
this);
+
+ for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) {
+ loading_queue->RemoveTaskObserver(
+ &MainThreadOnly().loading_task_cost_estimator);
+ }
+ for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) {
+ timer_queue->RemoveTaskObserver(
+ &MainThreadOnly().timer_task_cost_estimator);
+ }
+
// Ensure the renderer scheduler was shut down explicitly, because otherwise
// we could end up having stale pointers to the Blink heap which has been
// terminated by this point.
- DCHECK(MainThreadOnly().was_shutdown_);
+ DCHECK(MainThreadOnly().was_shutdown);
}
+RendererSchedulerImpl::Policy::Policy()
+ : compositor_queue_priority(TaskQueue::NORMAL_PRIORITY),
+ loading_queue_priority(TaskQueue::NORMAL_PRIORITY),
+ timer_queue_priority(TaskQueue::NORMAL_PRIORITY),
+ default_queue_priority(TaskQueue::NORMAL_PRIORITY) {}
+
RendererSchedulerImpl::MainThreadOnly::MainThreadOnly()
- : current_policy_(Policy::NORMAL),
- timer_queue_suspend_count_(0),
- renderer_hidden_(false),
- was_shutdown_(false) {
-}
+ : loading_task_cost_estimator(kLoadingTaskEstimationSampleCount,
+ kLoadingTaskEstimationPercentile),
+ timer_task_cost_estimator(kTimerTaskEstimationSampleCount,
+ kTimerTaskEstimationPercentile),
+ short_idle_period_duration(kShortIdlePeriodDurationSampleCount),
+ current_use_case(UseCase::NONE),
+ timer_queue_suspend_count(0),
+ navigation_task_expected_count(0),
+ renderer_hidden(false),
+ renderer_backgrounded(false),
+ timer_queue_suspension_when_backgrounded_enabled(false),
+ timer_queue_suspended_when_backgrounded(false),
+ was_shutdown(false),
+ loading_tasks_seem_expensive(false),
+ timer_tasks_seem_expensive(false),
+ touchstart_expected_soon(false),
+ have_seen_a_begin_main_frame(false) {}
+
+RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {}
RendererSchedulerImpl::AnyThread::AnyThread()
- : pending_main_thread_input_event_count_(0),
- awaiting_touch_start_response_(false),
- in_idle_period_(false),
- begin_main_frame_on_critical_path_(false) {
-}
+ : awaiting_touch_start_response(false),
+ in_idle_period(false),
+ begin_main_frame_on_critical_path(false) {}
RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly()
- : last_input_type_(blink::WebInputEvent::Undefined) {
-}
+ : last_input_type(blink::WebInputEvent::Undefined) {}
RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {
}
void RendererSchedulerImpl::Shutdown() {
helper_.Shutdown();
- MainThreadOnly().was_shutdown_ = true;
+ MainThreadOnly().was_shutdown = true;
}
scoped_refptr<TaskQueue> RendererSchedulerImpl::DefaultTaskRunner() {
@@ -108,12 +149,51 @@ RendererSchedulerImpl::IdleTaskRunner() {
scoped_refptr<base::SingleThreadTaskRunner>
RendererSchedulerImpl::LoadingTaskRunner() {
helper_.CheckOnValidThread();
- return loading_task_runner_;
+ return default_loading_task_runner_;
}
scoped_refptr<TaskQueue> RendererSchedulerImpl::TimerTaskRunner() {
helper_.CheckOnValidThread();
- return timer_task_runner_;
+ return default_timer_task_runner_;
+}
+
+scoped_refptr<TaskQueue> RendererSchedulerImpl::NewLoadingTaskRunner(
+ const char* name) {
+ helper_.CheckOnValidThread();
+ scoped_refptr<TaskQueue> loading_task_queue(helper_.NewTaskQueue(
+ TaskQueue::Spec(name).SetShouldMonitorQuiescence(true)));
+ loading_task_runners_.insert(loading_task_queue);
+ loading_task_queue->SetQueuePriority(
+ MainThreadOnly().current_policy.loading_queue_priority);
+ loading_task_queue->AddTaskObserver(
+ &MainThreadOnly().loading_task_cost_estimator);
+ return loading_task_queue;
+}
+
+scoped_refptr<TaskQueue> RendererSchedulerImpl::NewTimerTaskRunner(
+ const char* name) {
+ helper_.CheckOnValidThread();
+ scoped_refptr<TaskQueue> timer_task_queue(helper_.NewTaskQueue(
+ TaskQueue::Spec(name).SetShouldMonitorQuiescence(true)));
+ timer_task_runners_.insert(timer_task_queue);
+ timer_task_queue->SetQueuePriority(
+ MainThreadOnly().current_policy.timer_queue_priority);
+ timer_task_queue->AddTaskObserver(
+ &MainThreadOnly().timer_task_cost_estimator);
+ return timer_task_queue;
+}
+
+void RendererSchedulerImpl::OnUnregisterTaskQueue(
+ const scoped_refptr<TaskQueue>& task_queue) {
+ if (loading_task_runners_.find(task_queue) != loading_task_runners_.end()) {
+ task_queue->RemoveTaskObserver(
+ &MainThreadOnly().loading_task_cost_estimator);
+ loading_task_runners_.erase(task_queue);
+ } else if (timer_task_runners_.find(task_queue) !=
+ timer_task_runners_.end()) {
+ task_queue->RemoveTaskObserver(&MainThreadOnly().timer_task_cost_estimator);
+ timer_task_runners_.erase(task_queue);
+ }
}
bool RendererSchedulerImpl::CanExceedIdleDeadlineIfRequired() const {
@@ -138,11 +218,11 @@ void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
return;
EndIdlePeriod();
- MainThreadOnly().estimated_next_frame_begin_ =
- args.frame_time + args.interval;
+ MainThreadOnly().estimated_next_frame_begin = args.frame_time + args.interval;
+ MainThreadOnly().have_seen_a_begin_main_frame = true;
{
base::AutoLock lock(any_thread_lock_);
- AnyThread().begin_main_frame_on_critical_path_ = args.on_critical_path;
+ AnyThread().begin_main_frame_on_critical_path = args.on_critical_path;
}
}
@@ -154,13 +234,22 @@ void RendererSchedulerImpl::DidCommitFrameToCompositor() {
return;
base::TimeTicks now(helper_.Now());
- if (now < MainThreadOnly().estimated_next_frame_begin_) {
+ if (now < MainThreadOnly().estimated_next_frame_begin) {
// TODO(rmcilroy): Consider reducing the idle period based on the runtime of
// the next pending delayed tasks (as currently done in for long idle times)
idle_helper_.StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now,
- MainThreadOnly().estimated_next_frame_begin_);
+ MainThreadOnly().estimated_next_frame_begin);
+ MainThreadOnly().short_idle_period_duration.InsertSample(
+ MainThreadOnly().estimated_next_frame_begin - now);
+ } else {
+ // There was no idle time :(
+ MainThreadOnly().short_idle_period_duration.InsertSample(base::TimeDelta());
}
+
+ MainThreadOnly().expected_short_idle_period_duration =
+ MainThreadOnly().short_idle_period_duration.Percentile(
+ kShortIdlePeriodDurationPercentile);
}
void RendererSchedulerImpl::BeginFrameNotExpectedSoon() {
@@ -177,7 +266,7 @@ void RendererSchedulerImpl::OnRendererHidden() {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
"RendererSchedulerImpl::OnRendererHidden");
helper_.CheckOnValidThread();
- if (helper_.IsShutdown() || MainThreadOnly().renderer_hidden_)
+ if (helper_.IsShutdown() || MainThreadOnly().renderer_hidden)
return;
idle_helper_.EnableLongIdlePeriod();
@@ -189,7 +278,7 @@ void RendererSchedulerImpl::OnRendererHidden() {
control_task_runner_->PostDelayedTask(
FROM_HERE, end_renderer_hidden_idle_period_closure_.callback(),
end_idle_when_hidden_delay);
- MainThreadOnly().renderer_hidden_ = true;
+ MainThreadOnly().renderer_hidden = true;
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
@@ -200,11 +289,11 @@ void RendererSchedulerImpl::OnRendererVisible() {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
"RendererSchedulerImpl::OnRendererVisible");
helper_.CheckOnValidThread();
- if (helper_.IsShutdown() || !MainThreadOnly().renderer_hidden_)
+ if (helper_.IsShutdown() || !MainThreadOnly().renderer_hidden)
return;
end_renderer_hidden_idle_period_closure_.Cancel();
- MainThreadOnly().renderer_hidden_ = false;
+ MainThreadOnly().renderer_hidden = false;
EndIdlePeriod();
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
@@ -212,6 +301,38 @@ void RendererSchedulerImpl::OnRendererVisible() {
this, AsValue(helper_.Now()));
}
+void RendererSchedulerImpl::OnRendererBackgrounded() {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
+ "RendererSchedulerImpl::OnRendererBackgrounded");
+ helper_.CheckOnValidThread();
+ if (helper_.IsShutdown() || MainThreadOnly().renderer_backgrounded)
+ return;
+
+ MainThreadOnly().renderer_backgrounded = true;
+ if (!MainThreadOnly().timer_queue_suspension_when_backgrounded_enabled)
+ return;
+
+ suspend_timers_when_backgrounded_closure_.Cancel();
+ base::TimeDelta suspend_timers_when_backgrounded_delay =
+ base::TimeDelta::FromMilliseconds(
+ kSuspendTimersWhenBackgroundedDelayMillis);
+ control_task_runner_->PostDelayedTask(
+ FROM_HERE, suspend_timers_when_backgrounded_closure_.callback(),
+ suspend_timers_when_backgrounded_delay);
+}
+
+void RendererSchedulerImpl::OnRendererForegrounded() {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
+ "RendererSchedulerImpl::OnRendererForegrounded");
+ helper_.CheckOnValidThread();
+ if (helper_.IsShutdown() || !MainThreadOnly().renderer_backgrounded)
+ return;
+
+ MainThreadOnly().renderer_backgrounded = false;
+ suspend_timers_when_backgrounded_closure_.Cancel();
+ ResumeTimerQueueWhenForegrounded();
+}
+
void RendererSchedulerImpl::EndIdlePeriod() {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
"RendererSchedulerImpl::EndIdlePeriod");
@@ -264,14 +385,27 @@ void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
InputEventState input_event_state) {
base::AutoLock lock(any_thread_lock_);
base::TimeTicks now = helper_.Now();
- bool was_in_compositor_priority = InputSignalsSuggestCompositorPriority(now);
+
+ // TODO(alexclarke): Move WebInputEventTraits where we can access it from here
+ // and record the name rather than the integer representation.
+ TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
+ "RendererSchedulerImpl::UpdateForInputEventOnCompositorThread",
+ "type", static_cast<int>(type), "input_event_state",
+ InputEventStateToString(input_event_state));
+
+ bool gesture_already_in_progress = InputSignalsSuggestGestureInProgress(now);
bool was_awaiting_touch_start_response =
- AnyThread().awaiting_touch_start_response_;
+ AnyThread().awaiting_touch_start_response;
+
+ AnyThread().user_model.DidStartProcessingInputEvent(type, now);
+
+ if (input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR)
+ AnyThread().user_model.DidFinishProcessingInputEvent(now);
if (type) {
switch (type) {
case blink::WebInputEvent::TouchStart:
- AnyThread().awaiting_touch_start_response_ = true;
+ AnyThread().awaiting_touch_start_response = true;
break;
case blink::WebInputEvent::TouchMove:
@@ -280,13 +414,14 @@ void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
// response prioritization is no longer necessary. Otherwise, the
// initial touchmove should preserve the touchstart response pending
// state.
- if (AnyThread().awaiting_touch_start_response_ &&
- CompositorThreadOnly().last_input_type_ ==
+ if (AnyThread().awaiting_touch_start_response &&
+ CompositorThreadOnly().last_input_type ==
blink::WebInputEvent::TouchMove) {
- AnyThread().awaiting_touch_start_response_ = false;
+ AnyThread().awaiting_touch_start_response = false;
}
break;
+ case blink::WebInputEvent::Undefined:
case blink::WebInputEvent::GestureTapDown:
case blink::WebInputEvent::GestureShowPress:
case blink::WebInputEvent::GestureFlingCancel:
@@ -296,22 +431,18 @@ void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
break;
default:
- AnyThread().awaiting_touch_start_response_ = false;
+ AnyThread().awaiting_touch_start_response = false;
break;
}
}
- // Avoid unnecessary policy updates, while in compositor priority.
- if (!was_in_compositor_priority ||
+ // Avoid unnecessary policy updates, while a gesture is already in progress.
+ if (!gesture_already_in_progress ||
was_awaiting_touch_start_response !=
- AnyThread().awaiting_touch_start_response_) {
+ AnyThread().awaiting_touch_start_response) {
EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
}
- AnyThread().last_input_signal_time_ = now;
- CompositorThreadOnly().last_input_type_ = type;
-
- if (input_event_state == InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD)
- AnyThread().pending_main_thread_input_event_count_++;
+ CompositorThreadOnly().last_input_type = type;
}
void RendererSchedulerImpl::DidHandleInputEventOnMainThread(
@@ -321,9 +452,7 @@ void RendererSchedulerImpl::DidHandleInputEventOnMainThread(
helper_.CheckOnValidThread();
if (ShouldPrioritizeInputEvent(web_input_event)) {
base::AutoLock lock(any_thread_lock_);
- AnyThread().last_input_signal_time_ = helper_.Now();
- if (AnyThread().pending_main_thread_input_event_count_ > 0)
- AnyThread().pending_main_thread_input_event_count_--;
+ AnyThread().user_model.DidFinishProcessingInputEvent(helper_.Now());
}
}
@@ -333,12 +462,12 @@ bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
return false;
MaybeUpdatePolicy();
- // The touchstart and compositor policies indicate a strong likelihood of
- // high-priority work in the near future.
- return MainThreadOnly().current_policy_ == Policy::COMPOSITOR_PRIORITY ||
- MainThreadOnly().current_policy_ ==
- Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY ||
- MainThreadOnly().current_policy_ == Policy::TOUCHSTART_PRIORITY;
+ // The touchstart and main-thread gesture use cases indicate a strong
+ // likelihood of high-priority work in the near future.
+ UseCase use_case = MainThreadOnly().current_use_case;
+ return MainThreadOnly().touchstart_expected_soon ||
+ use_case == UseCase::TOUCHSTART ||
+ use_case == UseCase::MAIN_THREAD_GESTURE;
}
bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
@@ -347,25 +476,26 @@ bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
return false;
MaybeUpdatePolicy();
- // We only yield if we are in the compositor priority and there is compositor
- // work outstanding, or if we are in the touchstart response priority.
- // Note: even though the control queue is higher priority we don't yield for
- // it since these tasks are not user-provided work and they are only intended
- // to run before the next task, not interrupt the tasks.
- switch (MainThreadOnly().current_policy_) {
- case Policy::NORMAL:
- return false;
-
- case Policy::COMPOSITOR_PRIORITY:
- return !helper_.IsQueueEmpty(COMPOSITOR_TASK_QUEUE);
-
- case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY:
- return !helper_.IsQueueEmpty(COMPOSITOR_TASK_QUEUE);
-
- case Policy::TOUCHSTART_PRIORITY:
+ // We only yield if there's a urgent task to be run now, or we are expecting
+ // one soon (touch start).
+ // Note: even though the control queue has the highest priority we don't yield
+ // for it since these tasks are not user-provided work and they are only
+ // intended to run before the next task, not interrupt the tasks.
+ switch (MainThreadOnly().current_use_case) {
+ case UseCase::NONE:
+ return MainThreadOnly().touchstart_expected_soon;
+
+ case UseCase::COMPOSITOR_GESTURE:
+ return MainThreadOnly().touchstart_expected_soon;
+
+ case UseCase::MAIN_THREAD_GESTURE:
+ return !compositor_task_runner_->IsQueueEmpty() ||
+ MainThreadOnly().touchstart_expected_soon;
+
+ case UseCase::TOUCHSTART:
return true;
- case Policy::LOADING_PRIORITY:
+ case UseCase::LOADING:
return false;
default:
@@ -416,92 +546,149 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
base::TimeTicks now = helper_.Now();
policy_may_need_update_.SetWhileLocked(false);
- base::TimeDelta new_policy_duration;
- Policy new_policy = ComputeNewPolicy(now, &new_policy_duration);
+ base::TimeDelta expected_use_case_duration;
+ UseCase use_case = ComputeCurrentUseCase(now, &expected_use_case_duration);
+ MainThreadOnly().current_use_case = use_case;
+
+ // TODO(alexclarke): We should wire up a signal from blink to let us know if
+ // there are any touch handlers registerd or not, and only call
+ // TouchStartExpectedSoon if there is at least one. NOTE a TouchStart will
+ // only actually get sent if there is a touch handler.
+ base::TimeDelta touchstart_expected_flag_valid_for_duration;
+ bool touchstart_expected_soon = AnyThread().user_model.IsGestureExpectedSoon(
+ use_case, now, &touchstart_expected_flag_valid_for_duration);
+ MainThreadOnly().touchstart_expected_soon = touchstart_expected_soon;
+
+ bool loading_tasks_seem_expensive =
+ MainThreadOnly().loading_task_cost_estimator.expected_task_duration() >
+ MainThreadOnly().expected_short_idle_period_duration;
+ MainThreadOnly().loading_tasks_seem_expensive = loading_tasks_seem_expensive;
+
+ bool timer_tasks_seem_expensive =
+ MainThreadOnly().timer_task_cost_estimator.expected_task_duration() >
+ MainThreadOnly().expected_short_idle_period_duration;
+ MainThreadOnly().timer_tasks_seem_expensive = timer_tasks_seem_expensive;
+
+ // The |new_policy_duration| is the minimum of |expected_use_case_duration|
+ // and |touchstart_expected_flag_valid_for_duration| unless one is zero in
+ // which case we choose the other.
+ base::TimeDelta new_policy_duration = expected_use_case_duration;
+ if (new_policy_duration == base::TimeDelta() ||
+ (touchstart_expected_flag_valid_for_duration > base::TimeDelta() &&
+ new_policy_duration > touchstart_expected_flag_valid_for_duration)) {
+ new_policy_duration = touchstart_expected_flag_valid_for_duration;
+ }
+
if (new_policy_duration > base::TimeDelta()) {
- MainThreadOnly().current_policy_expiration_time_ =
- now + new_policy_duration;
+ MainThreadOnly().current_policy_expiration_time = now + new_policy_duration;
delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration,
now);
} else {
- MainThreadOnly().current_policy_expiration_time_ = base::TimeTicks();
+ MainThreadOnly().current_policy_expiration_time = base::TimeTicks();
}
- if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED &&
- new_policy == MainThreadOnly().current_policy_)
- return;
-
- bool policy_disables_timer_queue = false;
- PrioritizingTaskQueueSelector::QueuePriority timer_queue_priority =
- PrioritizingTaskQueueSelector::NORMAL_PRIORITY;
-
- switch (new_policy) {
- case Policy::COMPOSITOR_PRIORITY:
- helper_.SetQueuePriority(COMPOSITOR_TASK_QUEUE,
- PrioritizingTaskQueueSelector::HIGH_PRIORITY);
- helper_.SetQueuePriority(LOADING_TASK_QUEUE,
- PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
+ Policy new_policy;
+ bool block_expensive_tasks = false;
+ switch (use_case) {
+ case UseCase::COMPOSITOR_GESTURE:
+ if (touchstart_expected_soon) {
+ block_expensive_tasks = true;
+ } else {
+ // What we really want to do is priorize loading tasks, but that doesn't
+ // seem to be safe. Instead we do that by proxy by deprioritizing
+ // compositor tasks. This should be safe since we've already gone to the
+ // pain of fixing ordering issues with them.
+ new_policy.compositor_queue_priority = TaskQueue::BEST_EFFORT_PRIORITY;
+ }
break;
- case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY:
- helper_.SetQueuePriority(COMPOSITOR_TASK_QUEUE,
- PrioritizingTaskQueueSelector::HIGH_PRIORITY);
- helper_.DisableQueue(LOADING_TASK_QUEUE);
- policy_disables_timer_queue = true;
+
+ case UseCase::MAIN_THREAD_GESTURE:
+ new_policy.compositor_queue_priority = TaskQueue::HIGH_PRIORITY;
+ block_expensive_tasks = true;
break;
- case Policy::TOUCHSTART_PRIORITY:
- helper_.SetQueuePriority(COMPOSITOR_TASK_QUEUE,
- PrioritizingTaskQueueSelector::HIGH_PRIORITY);
- helper_.DisableQueue(LOADING_TASK_QUEUE);
- policy_disables_timer_queue = true;
+
+ case UseCase::TOUCHSTART:
+ new_policy.compositor_queue_priority = TaskQueue::HIGH_PRIORITY;
+ new_policy.loading_queue_priority = TaskQueue::DISABLED_PRIORITY;
+ new_policy.timer_queue_priority = TaskQueue::DISABLED_PRIORITY;
+ block_expensive_tasks = true; // NOTE this is a nop due to the above.
break;
- case Policy::NORMAL:
- helper_.SetQueuePriority(COMPOSITOR_TASK_QUEUE,
- PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
- helper_.SetQueuePriority(LOADING_TASK_QUEUE,
- PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
+
+ case UseCase::NONE:
+ if (touchstart_expected_soon)
+ block_expensive_tasks = true;
break;
- case Policy::LOADING_PRIORITY:
- // We prioritize loading tasks by deprioritizing compositing and timers.
- helper_.SetQueuePriority(LOADING_TASK_QUEUE,
- PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
- helper_.SetQueuePriority(
- COMPOSITOR_TASK_QUEUE,
- PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
- timer_queue_priority =
- PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY;
- // TODO(alexclarke): See if we can safely mark the loading task queue as
- // high priority.
+
+ case UseCase::LOADING:
+ new_policy.loading_queue_priority = TaskQueue::HIGH_PRIORITY;
+ new_policy.default_queue_priority = TaskQueue::HIGH_PRIORITY;
break;
+
default:
NOTREACHED();
}
- if (MainThreadOnly().timer_queue_suspend_count_ != 0 ||
- policy_disables_timer_queue) {
- helper_.DisableQueue(TIMER_TASK_QUEUE);
- } else {
- helper_.SetQueuePriority(TIMER_TASK_QUEUE, timer_queue_priority);
- }
- DCHECK(helper_.IsQueueEnabled(COMPOSITOR_TASK_QUEUE));
- if (new_policy != Policy::TOUCHSTART_PRIORITY &&
- new_policy != Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY) {
- DCHECK(helper_.IsQueueEnabled(LOADING_TASK_QUEUE));
+
+ // Don't block expensive tasks unless we have actually seen something.
+ if (!MainThreadOnly().have_seen_a_begin_main_frame)
+ block_expensive_tasks = false;
+
+ // Don't block expensive tasks if we are expecting a navigation.
+ if (MainThreadOnly().navigation_task_expected_count > 0)
+ block_expensive_tasks = false;
+
+ if (block_expensive_tasks && loading_tasks_seem_expensive)
+ new_policy.loading_queue_priority = TaskQueue::DISABLED_PRIORITY;
+
+ if (MainThreadOnly().timer_queue_suspend_count != 0 ||
+ MainThreadOnly().timer_queue_suspended_when_backgrounded) {
+ new_policy.timer_queue_priority = TaskQueue::DISABLED_PRIORITY;
}
- MainThreadOnly().current_policy_ = new_policy;
+ // Tracing is done before the early out check, because it's quite possible we
+ // will otherwise miss this information in traces.
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
this, AsValueLocked(now));
+ TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "use_case",
+ use_case);
+ TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
+ "RendererScheduler.loading_tasks_seem_expensive",
+ MainThreadOnly().loading_tasks_seem_expensive);
TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
- "RendererScheduler.policy", MainThreadOnly().current_policy_);
+ "RendererScheduler.timer_tasks_seem_expensive",
+ MainThreadOnly().timer_tasks_seem_expensive);
+
+ if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED &&
+ new_policy == MainThreadOnly().current_policy) {
+ return;
+ }
+
+ compositor_task_runner_->SetQueuePriority(
+ new_policy.compositor_queue_priority);
+ for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) {
+ loading_queue->SetQueuePriority(new_policy.loading_queue_priority);
+ }
+ for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) {
+ timer_queue->SetQueuePriority(new_policy.timer_queue_priority);
+ }
+
+ // TODO(alexclarke): We shouldn't have to prioritize the default queue, but it
+ // appears to be necessary since the order of loading tasks and IPCs (which
+ // are mostly dispatched on the default queue) need to be preserved.
+ helper_.DefaultTaskRunner()->SetQueuePriority(
+ new_policy.default_queue_priority);
+
+ DCHECK(compositor_task_runner_->IsQueueEnabled());
+ MainThreadOnly().current_policy = new_policy;
}
-bool RendererSchedulerImpl::InputSignalsSuggestCompositorPriority(
+bool RendererSchedulerImpl::InputSignalsSuggestGestureInProgress(
base::TimeTicks now) const {
base::TimeDelta unused_policy_duration;
- switch (ComputeNewPolicy(now, &unused_policy_duration)) {
- case Policy::TOUCHSTART_PRIORITY:
- case Policy::COMPOSITOR_PRIORITY:
- case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY:
+ switch (ComputeCurrentUseCase(now, &unused_policy_duration)) {
+ case UseCase::COMPOSITOR_GESTURE:
+ case UseCase::MAIN_THREAD_GESTURE:
+ case UseCase::TOUCHSTART:
return true;
default:
@@ -510,57 +697,35 @@ bool RendererSchedulerImpl::InputSignalsSuggestCompositorPriority(
return false;
}
-RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy(
+RendererSchedulerImpl::UseCase RendererSchedulerImpl::ComputeCurrentUseCase(
base::TimeTicks now,
- base::TimeDelta* new_policy_duration) const {
+ base::TimeDelta* expected_use_case_duration) const {
any_thread_lock_.AssertAcquired();
// Above all else we want to be responsive to user input.
- *new_policy_duration = TimeLeftInInputEscalatedPolicy(now);
- if (*new_policy_duration > base::TimeDelta()) {
- if (AnyThread().awaiting_touch_start_response_)
- return Policy::TOUCHSTART_PRIORITY;
- // If BeginMainFrame is on the critical path, we want to try and prevent
- // timers and loading tasks from running shortly before BeginMainFrame is
- // due to be posted from the compositor, because they can delay
- // BeginMainFrame's execution. We do this by limiting execution of timers to
- // idle periods, provided there has been at least one idle period recently.
- //
- // TODO(alexclarke): It's a shame in_idle_period_,
- // begin_main_frame_on_critical_path_ and last_idle_period_end_time_ are in
- // the AnyThread struct. Find a way to migrate them to MainThreadOnly.
- if (!AnyThread().in_idle_period_ &&
- AnyThread().begin_main_frame_on_critical_path_ &&
- HadAnIdlePeriodRecently(now)) {
- return Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY;
+ *expected_use_case_duration =
+ AnyThread().user_model.TimeLeftInUserGesture(now);
+ if (*expected_use_case_duration > base::TimeDelta()) {
+ // Has scrolling been fully established?
+ if (AnyThread().awaiting_touch_start_response) {
+ // No, so arrange for compositor tasks to be run at the highest priority.
+ return UseCase::TOUCHSTART;
+ }
+ // Yes scrolling has been established. If BeginMainFrame is on the critical
+ // path, compositor tasks need to be prioritized, otherwise now might be a
+ // good time to run potentially expensive work.
+ // TODO(skyostil): Consider removing in_idle_period_ and
+ // HadAnIdlePeriodRecently() unless we need them here.
+ if (AnyThread().begin_main_frame_on_critical_path) {
+ return UseCase::MAIN_THREAD_GESTURE;
+ } else {
+ return UseCase::COMPOSITOR_GESTURE;
}
- return Policy::COMPOSITOR_PRIORITY;
- }
-
- if (AnyThread().rails_loading_priority_deadline_ > now) {
- *new_policy_duration = AnyThread().rails_loading_priority_deadline_ - now;
- return Policy::LOADING_PRIORITY;
}
- return Policy::NORMAL;
-}
-
-base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy(
- base::TimeTicks now) const {
- any_thread_lock_.AssertAcquired();
-
- base::TimeDelta escalated_priority_duration =
- base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis);
+ // TODO(alexclarke): return UseCase::LOADING if signals suggest the system is
+ // in the initial 1s of RAIL loading.
- // If the input event is still pending, go into input prioritized policy
- // and check again later.
- if (AnyThread().pending_main_thread_input_event_count_ > 0)
- return escalated_priority_duration;
- if (AnyThread().last_input_signal_time_.is_null() ||
- AnyThread().last_input_signal_time_ + escalated_priority_duration < now) {
- return base::TimeDelta();
- }
- return AnyThread().last_input_signal_time_ + escalated_priority_duration -
- now;
+ return UseCase::NONE;
}
bool RendererSchedulerImpl::CanEnterLongIdlePeriod(
@@ -569,11 +734,11 @@ bool RendererSchedulerImpl::CanEnterLongIdlePeriod(
helper_.CheckOnValidThread();
MaybeUpdatePolicy();
- if (MainThreadOnly().current_policy_ == Policy::TOUCHSTART_PRIORITY) {
+ if (MainThreadOnly().current_use_case == UseCase::TOUCHSTART) {
// Don't start a long idle task in touch start priority, try again when
// the policy is scheduled to end.
*next_long_idle_period_delay_out =
- MainThreadOnly().current_policy_expiration_time_ - now;
+ MainThreadOnly().current_policy_expiration_time - now;
return false;
}
return true;
@@ -583,52 +748,37 @@ SchedulerHelper* RendererSchedulerImpl::GetSchedulerHelperForTesting() {
return &helper_;
}
+TaskCostEstimator*
+RendererSchedulerImpl::GetLoadingTaskCostEstimatorForTesting() {
+ return &MainThreadOnly().loading_task_cost_estimator;
+}
+
+TaskCostEstimator*
+RendererSchedulerImpl::GetTimerTaskCostEstimatorForTesting() {
+ return &MainThreadOnly().timer_task_cost_estimator;
+}
+
void RendererSchedulerImpl::SuspendTimerQueue() {
- MainThreadOnly().timer_queue_suspend_count_++;
+ MainThreadOnly().timer_queue_suspend_count++;
ForceUpdatePolicy();
- DCHECK(!helper_.IsQueueEnabled(TIMER_TASK_QUEUE));
+#ifndef NDEBUG
+ DCHECK(!default_timer_task_runner_->IsQueueEnabled());
+ for (const auto& runner : timer_task_runners_) {
+ DCHECK(!runner->IsQueueEnabled());
+ }
+#endif
}
void RendererSchedulerImpl::ResumeTimerQueue() {
- MainThreadOnly().timer_queue_suspend_count_--;
- DCHECK_GE(MainThreadOnly().timer_queue_suspend_count_, 0);
+ MainThreadOnly().timer_queue_suspend_count--;
+ DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0);
ForceUpdatePolicy();
}
-// static
-const char* RendererSchedulerImpl::TaskQueueIdToString(QueueId queue_id) {
- switch (queue_id) {
- case IDLE_TASK_QUEUE:
- return "idle_tq";
- case COMPOSITOR_TASK_QUEUE:
- return "compositor_tq";
- case LOADING_TASK_QUEUE:
- return "loading_tq";
- case TIMER_TASK_QUEUE:
- return "timer_tq";
- default:
- return SchedulerHelper::TaskQueueIdToString(
- static_cast<SchedulerHelper::QueueId>(queue_id));
- }
-}
-
-// static
-const char* RendererSchedulerImpl::PolicyToString(Policy policy) {
- switch (policy) {
- case Policy::NORMAL:
- return "normal";
- case Policy::COMPOSITOR_PRIORITY:
- return "compositor";
- case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY:
- return "compositor_critical_path";
- case Policy::TOUCHSTART_PRIORITY:
- return "touchstart";
- case Policy::LOADING_PRIORITY:
- return "loading";
- default:
- NOTREACHED();
- return nullptr;
- }
+void RendererSchedulerImpl::SetTimerQueueSuspensionWhenBackgroundedEnabled(
+ bool enabled) {
+ // Note that this will only take effect for the next backgrounded signal.
+ MainThreadOnly().timer_queue_suspension_when_backgrounded_enabled = enabled;
}
scoped_refptr<base::trace_event::ConvertableToTraceFormat>
@@ -647,61 +797,133 @@ RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
scoped_refptr<base::trace_event::TracedValue> state =
new base::trace_event::TracedValue();
- state->SetString("current_policy",
- PolicyToString(MainThreadOnly().current_policy_));
+ state->SetString("current_use_case",
+ UseCaseToString(MainThreadOnly().current_use_case));
+ state->SetBoolean("loading_tasks_seem_expensive",
+ MainThreadOnly().loading_tasks_seem_expensive);
+ state->SetBoolean("timer_tasks_seem_expensive",
+ MainThreadOnly().timer_tasks_seem_expensive);
+ state->SetBoolean("touchstart_expected_soon",
+ MainThreadOnly().touchstart_expected_soon);
state->SetString("idle_period_state",
IdleHelper::IdlePeriodStateToString(
idle_helper_.SchedulerIdlePeriodState()));
- state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden_);
+ state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden);
+ state->SetBoolean("renderer_backgrounded",
+ MainThreadOnly().renderer_backgrounded);
+ state->SetBoolean("timer_queue_suspended_when_backgrounded",
+ MainThreadOnly().timer_queue_suspended_when_backgrounded);
+ state->SetInteger("timer_queue_suspend_count",
+ MainThreadOnly().timer_queue_suspend_count);
state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF());
- state->SetDouble("last_input_signal_time",
- (AnyThread().last_input_signal_time_ - base::TimeTicks())
- .InMillisecondsF());
- state->SetDouble("rails_loading_priority_deadline",
- (AnyThread().rails_loading_priority_deadline_ -
- base::TimeTicks()).InMillisecondsF());
+ state->SetDouble(
+ "rails_loading_priority_deadline",
+ (AnyThread().rails_loading_priority_deadline - base::TimeTicks())
+ .InMillisecondsF());
+ state->SetInteger("navigation_task_expected_count",
+ MainThreadOnly().navigation_task_expected_count);
state->SetDouble("last_idle_period_end_time",
- (AnyThread().last_idle_period_end_time_ - base::TimeTicks())
+ (AnyThread().last_idle_period_end_time - base::TimeTicks())
.InMillisecondsF());
- state->SetInteger("pending_main_thread_input_event_count",
- AnyThread().pending_main_thread_input_event_count_);
state->SetBoolean("awaiting_touch_start_response",
- AnyThread().awaiting_touch_start_response_);
+ AnyThread().awaiting_touch_start_response);
state->SetBoolean("begin_main_frame_on_critical_path",
- AnyThread().begin_main_frame_on_critical_path_);
- state->SetDouble("estimated_next_frame_begin",
- (MainThreadOnly().estimated_next_frame_begin_ -
- base::TimeTicks()).InMillisecondsF());
- state->SetBoolean("in_idle_period", AnyThread().in_idle_period_);
+ AnyThread().begin_main_frame_on_critical_path);
+ state->SetDouble("expected_loading_task_duration",
+ MainThreadOnly()
+ .loading_task_cost_estimator.expected_task_duration()
+ .InMillisecondsF());
+ state->SetDouble("expected_timer_task_duration",
+ MainThreadOnly()
+ .timer_task_cost_estimator.expected_task_duration()
+ .InMillisecondsF());
+ // TODO(skyostil): Can we somehow trace how accurate these estimates were?
+ state->SetDouble(
+ "expected_short_idle_period_duration",
+ MainThreadOnly().expected_short_idle_period_duration.InMillisecondsF());
+ state->SetDouble(
+ "estimated_next_frame_begin",
+ (MainThreadOnly().estimated_next_frame_begin - base::TimeTicks())
+ .InMillisecondsF());
+ state->SetBoolean("in_idle_period", AnyThread().in_idle_period);
+ AnyThread().user_model.AsValueInto(state.get());
return state;
}
void RendererSchedulerImpl::OnIdlePeriodStarted() {
base::AutoLock lock(any_thread_lock_);
- AnyThread().in_idle_period_ = true;
+ AnyThread().in_idle_period = true;
UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
}
void RendererSchedulerImpl::OnIdlePeriodEnded() {
base::AutoLock lock(any_thread_lock_);
- AnyThread().last_idle_period_end_time_ = helper_.Now();
- AnyThread().in_idle_period_ = false;
+ AnyThread().last_idle_period_end_time = helper_.Now();
+ AnyThread().in_idle_period = false;
UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
}
-void RendererSchedulerImpl::OnPageLoadStarted() {
+void RendererSchedulerImpl::AddPendingNavigation() {
+ helper_.CheckOnValidThread();
+ MainThreadOnly().navigation_task_expected_count++;
+ UpdatePolicy();
+}
+
+void RendererSchedulerImpl::RemovePendingNavigation() {
+ helper_.CheckOnValidThread();
+ DCHECK_GT(MainThreadOnly().navigation_task_expected_count, 0);
+ if (MainThreadOnly().navigation_task_expected_count > 0)
+ MainThreadOnly().navigation_task_expected_count--;
+ UpdatePolicy();
+}
+
+void RendererSchedulerImpl::OnNavigationStarted() {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
+ "RendererSchedulerImpl::OnNavigationStarted");
base::AutoLock lock(any_thread_lock_);
- AnyThread().rails_loading_priority_deadline_ =
+ AnyThread().rails_loading_priority_deadline =
helper_.Now() + base::TimeDelta::FromMilliseconds(
kRailsInitialLoadingPrioritizationMillis);
- UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
+ ResetForNavigationLocked();
}
bool RendererSchedulerImpl::HadAnIdlePeriodRecently(base::TimeTicks now) const {
- return (now - AnyThread().last_idle_period_end_time_) <=
+ return (now - AnyThread().last_idle_period_end_time) <=
base::TimeDelta::FromMilliseconds(
kIdlePeriodStarvationThresholdMillis);
}
+void RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded() {
+ DCHECK(MainThreadOnly().renderer_backgrounded);
+ if (MainThreadOnly().timer_queue_suspended_when_backgrounded)
+ return;
+
+ MainThreadOnly().timer_queue_suspended_when_backgrounded = true;
+ ForceUpdatePolicy();
+}
+
+void RendererSchedulerImpl::ResumeTimerQueueWhenForegrounded() {
+ DCHECK(!MainThreadOnly().renderer_backgrounded);
+ if (!MainThreadOnly().timer_queue_suspended_when_backgrounded)
+ return;
+
+ MainThreadOnly().timer_queue_suspended_when_backgrounded = false;
+ ForceUpdatePolicy();
+}
+
+void RendererSchedulerImpl::ResetForNavigationLocked() {
+ helper_.CheckOnValidThread();
+ any_thread_lock_.AssertAcquired();
+ MainThreadOnly().loading_task_cost_estimator.Clear();
+ MainThreadOnly().timer_task_cost_estimator.Clear();
+ MainThreadOnly().short_idle_period_duration.Clear();
+ // Make sure that we don't initially assume there is no idle time.
+ MainThreadOnly().short_idle_period_duration.InsertSample(
+ cc::BeginFrameArgs::DefaultInterval());
+ AnyThread().user_model.Reset();
+ MainThreadOnly().have_seen_a_begin_main_frame = false;
+ UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
+}
+
} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/renderer_scheduler_impl.h b/chromium/components/scheduler/renderer/renderer_scheduler_impl.h
index e25153827a2..dbe1c003cd6 100644
--- a/chromium/components/scheduler/renderer/renderer_scheduler_impl.h
+++ b/chromium/components/scheduler/renderer/renderer_scheduler_impl.h
@@ -7,11 +7,13 @@
#include "base/atomicops.h"
#include "base/synchronization/lock.h"
+#include "components/scheduler/base/pollable_thread_safe_flag.h"
#include "components/scheduler/child/idle_helper.h"
-#include "components/scheduler/child/pollable_thread_safe_flag.h"
#include "components/scheduler/child/scheduler_helper.h"
#include "components/scheduler/renderer/deadline_task_runner.h"
#include "components/scheduler/renderer/renderer_scheduler.h"
+#include "components/scheduler/renderer/task_cost_estimator.h"
+#include "components/scheduler/renderer/user_model.h"
#include "components/scheduler/scheduler_export.h"
namespace base {
@@ -22,11 +24,13 @@ class ConvertableToTraceFormat;
namespace scheduler {
-class SCHEDULER_EXPORT RendererSchedulerImpl : public RendererScheduler,
- public IdleHelper::Delegate {
+class SCHEDULER_EXPORT RendererSchedulerImpl
+ : public RendererScheduler,
+ public IdleHelper::Delegate,
+ public SchedulerHelper::Observer {
public:
RendererSchedulerImpl(
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner);
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner);
~RendererSchedulerImpl() override;
// RendererScheduler implementation:
@@ -35,6 +39,8 @@ class SCHEDULER_EXPORT RendererSchedulerImpl : public RendererScheduler,
scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> LoadingTaskRunner() override;
scoped_refptr<TaskQueue> TimerTaskRunner() override;
+ scoped_refptr<TaskQueue> NewLoadingTaskRunner(const char* name) override;
+ scoped_refptr<TaskQueue> NewTimerTaskRunner(const char* name) override;
void WillBeginFrame(const cc::BeginFrameArgs& args) override;
void BeginFrameNotExpectedSoon() override;
void DidCommitFrameToCompositor() override;
@@ -46,7 +52,11 @@ class SCHEDULER_EXPORT RendererSchedulerImpl : public RendererScheduler,
void DidAnimateForInputOnCompositorThread() override;
void OnRendererHidden() override;
void OnRendererVisible() override;
- void OnPageLoadStarted() override;
+ void OnRendererBackgrounded() override;
+ void OnRendererForegrounded() override;
+ void AddPendingNavigation() override;
+ void RemovePendingNavigation() override;
+ void OnNavigationStarted() override;
bool IsHighPriorityWorkAnticipated() override;
bool ShouldYieldForHighPriorityWork() override;
bool CanExceedIdleDeadlineIfRequired() const override;
@@ -56,35 +66,35 @@ class SCHEDULER_EXPORT RendererSchedulerImpl : public RendererScheduler,
void Shutdown() override;
void SuspendTimerQueue() override;
void ResumeTimerQueue() override;
+ void SetTimerQueueSuspensionWhenBackgroundedEnabled(bool enabled) override;
+ // TaskQueueManager::Observer implementation:
+ void OnUnregisterTaskQueue(const scoped_refptr<TaskQueue>& queue) override;
+
+ // Test helpers.
SchedulerHelper* GetSchedulerHelperForTesting();
+ TaskCostEstimator* GetLoadingTaskCostEstimatorForTesting();
+ TaskCostEstimator* GetTimerTaskCostEstimatorForTesting();
base::TimeTicks CurrentIdleTaskDeadlineForTesting() const;
private:
friend class RendererSchedulerImplTest;
friend class RendererSchedulerImplForTest;
- // Keep RendererSchedulerImpl::TaskQueueIdToString in sync with this enum.
- enum QueueId {
- IDLE_TASK_QUEUE = SchedulerHelper::TASK_QUEUE_COUNT,
- COMPOSITOR_TASK_QUEUE,
- LOADING_TASK_QUEUE,
- TIMER_TASK_QUEUE,
- // Must be the last entry.
- TASK_QUEUE_COUNT,
- FIRST_QUEUE_ID = SchedulerHelper::FIRST_QUEUE_ID,
- };
+ struct Policy {
+ Policy();
+
+ TaskQueue::QueuePriority compositor_queue_priority;
+ TaskQueue::QueuePriority loading_queue_priority;
+ TaskQueue::QueuePriority timer_queue_priority;
+ TaskQueue::QueuePriority default_queue_priority;
- // Keep RendererSchedulerImpl::PolicyToString in sync with this enum.
- enum class Policy {
- NORMAL,
- COMPOSITOR_PRIORITY,
- COMPOSITOR_CRITICAL_PATH_PRIORITY,
- TOUCHSTART_PRIORITY,
- LOADING_PRIORITY,
- // Must be the last entry.
- POLICY_COUNT,
- FIRST_POLICY = NORMAL,
+ bool operator==(const Policy& other) const {
+ return compositor_queue_priority == other.compositor_queue_priority &&
+ loading_queue_priority == other.loading_queue_priority &&
+ timer_queue_priority == other.timer_queue_priority &&
+ default_queue_priority == other.default_queue_priority;
+ }
};
class PollableNeedsUpdateFlag {
@@ -120,15 +130,10 @@ class SCHEDULER_EXPORT RendererSchedulerImpl : public RendererScheduler,
base::TimeTicks optional_now) const;
scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked(
base::TimeTicks optional_now) const;
- static const char* TaskQueueIdToString(QueueId queue_id);
- static const char* PolicyToString(Policy policy);
static bool ShouldPrioritizeInputEvent(
const blink::WebInputEvent& web_input_event);
- // The time we should stay in a priority-escalated mode after an input event.
- static const int kPriorityEscalationAfterInputMillis = 100;
-
// The amount of time which idle periods can continue being scheduled when the
// renderer has been hidden, before going to sleep for good.
static const int kEndIdleWhenHiddenDelayMillis = 10000;
@@ -144,6 +149,11 @@ class SCHEDULER_EXPORT RendererSchedulerImpl : public RendererScheduler,
// user gestures.
static const int kIdlePeriodStarvationThresholdMillis = 10000;
+ // The amount of time to wait before suspending shared timers after the
+ // renderer has been backgrounded. This is used only if background suspension
+ // of shared timers is enabled.
+ static const int kSuspendTimersWhenBackgroundedDelayMillis = 5 * 60 * 1000;
+
// Schedules an immediate PolicyUpdate, if there isn't one already pending and
// sets |policy_may_need_update_|. Note |any_thread_lock_| must be
// locked.
@@ -170,20 +180,18 @@ class SCHEDULER_EXPORT RendererSchedulerImpl : public RendererScheduler,
// early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED.
virtual void UpdatePolicyLocked(UpdateType update_type);
- // Returns the amount of time left in the current input escalated priority
- // policy. Can be called from any thread.
- base::TimeDelta TimeLeftInInputEscalatedPolicy(base::TimeTicks now) const;
-
- // Helper for computing the new policy. |new_policy_duration| will be filled
- // with the amount of time after which the policy should be updated again. If
- // the duration is zero, a new policy update will not be scheduled. Must be
- // called with |any_thread_lock_| held. Can be called from any thread.
- Policy ComputeNewPolicy(base::TimeTicks now,
- base::TimeDelta* new_policy_duration) const;
+ // Helper for computing the use case. |expected_usecase_duration| will be
+ // filled with the amount of time after which the use case should be updated
+ // again. If the duration is zero, a new use case update should not be
+ // scheduled. Must be called with |any_thread_lock_| held. Can be called from
+ // any thread.
+ UseCase ComputeCurrentUseCase(
+ base::TimeTicks now,
+ base::TimeDelta* expected_use_case_duration) const;
- // Works out if compositor tasks would be prioritized based on the current
- // input signals. Can be called from any thread.
- bool InputSignalsSuggestCompositorPriority(base::TimeTicks now) const;
+ // Works out if a gesture appears to be in progress based on the current
+ // input signals. Can be called from any thread.
+ bool InputSignalsSuggestGestureInProgress(base::TimeTicks now) const;
// An input event of some sort happened, the policy may need updating.
void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type,
@@ -193,58 +201,83 @@ class SCHEDULER_EXPORT RendererSchedulerImpl : public RendererScheduler,
// |kIdlePeriodStarvationThresholdMillis|.
bool HadAnIdlePeriodRecently(base::TimeTicks now) const;
+ // Helpers for safely suspending/resuming the timer queue after a
+ // background/foreground signal.
+ void SuspendTimerQueueWhenBackgrounded();
+ void ResumeTimerQueueWhenForegrounded();
+
+ // The task cost estimators and the UserModel need to be reset upon page
+ // nagigation. This function does that. Must be called from the main thread.
+ void ResetForNavigationLocked();
+
SchedulerHelper helper_;
IdleHelper idle_helper_;
- const scoped_refptr<base::SingleThreadTaskRunner> control_task_runner_;
- const scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
- const scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
- const scoped_refptr<TaskQueue> timer_task_runner_;
+ const scoped_refptr<TaskQueue> control_task_runner_;
+ const scoped_refptr<TaskQueue> compositor_task_runner_;
+ std::set<scoped_refptr<TaskQueue>> loading_task_runners_;
+ std::set<scoped_refptr<TaskQueue>> timer_task_runners_;
+ scoped_refptr<TaskQueue> default_loading_task_runner_;
+ scoped_refptr<TaskQueue> default_timer_task_runner_;
base::Closure update_policy_closure_;
DeadlineTaskRunner delayed_update_policy_runner_;
CancelableClosureHolder end_renderer_hidden_idle_period_closure_;
+ CancelableClosureHolder suspend_timers_when_backgrounded_closure_;
// We have decided to improve thread safety at the cost of some boilerplate
// (the accessors) for the following data members.
struct MainThreadOnly {
MainThreadOnly();
-
- Policy current_policy_;
- base::TimeTicks current_policy_expiration_time_;
- base::TimeTicks estimated_next_frame_begin_;
- int timer_queue_suspend_count_; // TIMER_TASK_QUEUE suspended if non-zero.
- bool renderer_hidden_;
- bool was_shutdown_;
+ ~MainThreadOnly();
+
+ TaskCostEstimator loading_task_cost_estimator;
+ TaskCostEstimator timer_task_cost_estimator;
+ cc::RollingTimeDeltaHistory short_idle_period_duration;
+ UseCase current_use_case;
+ Policy current_policy;
+ base::TimeTicks current_policy_expiration_time;
+ base::TimeTicks estimated_next_frame_begin;
+ base::TimeDelta expected_short_idle_period_duration;
+ int timer_queue_suspend_count; // TIMER_TASK_QUEUE suspended if non-zero.
+ int navigation_task_expected_count;
+ bool renderer_hidden;
+ bool renderer_backgrounded;
+ bool timer_queue_suspension_when_backgrounded_enabled;
+ bool timer_queue_suspended_when_backgrounded;
+ bool was_shutdown;
+ bool loading_tasks_seem_expensive;
+ bool timer_tasks_seem_expensive;
+ bool touchstart_expected_soon;
+ bool have_seen_a_begin_main_frame;
};
struct AnyThread {
AnyThread();
- base::TimeTicks last_input_signal_time_;
- base::TimeTicks last_idle_period_end_time_;
- base::TimeTicks rails_loading_priority_deadline_;
- int pending_main_thread_input_event_count_;
- bool awaiting_touch_start_response_;
- bool in_idle_period_;
- bool begin_main_frame_on_critical_path_;
+ base::TimeTicks last_idle_period_end_time;
+ base::TimeTicks rails_loading_priority_deadline;
+ UserModel user_model;
+ bool awaiting_touch_start_response;
+ bool in_idle_period;
+ bool begin_main_frame_on_critical_path;
};
struct CompositorThreadOnly {
CompositorThreadOnly();
~CompositorThreadOnly();
- blink::WebInputEvent::Type last_input_type_;
- scoped_ptr<base::ThreadChecker> compositor_thread_checker_;
+ blink::WebInputEvent::Type last_input_type;
+ scoped_ptr<base::ThreadChecker> compositor_thread_checker;
void CheckOnValidThread() {
#if DCHECK_IS_ON()
// We don't actually care which thread this called from, just so long as
// its consistent.
- if (!compositor_thread_checker_)
- compositor_thread_checker_.reset(new base::ThreadChecker());
- DCHECK(compositor_thread_checker_->CalledOnValidThread());
+ if (!compositor_thread_checker)
+ compositor_thread_checker.reset(new base::ThreadChecker());
+ DCHECK(compositor_thread_checker->CalledOnValidThread());
#endif
}
};
diff --git a/chromium/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc b/chromium/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc
index b860b1986a6..4956bf135d1 100644
--- a/chromium/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc
+++ b/chromium/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc
@@ -8,9 +8,9 @@
#include "base/test/simple_test_tick_clock.h"
#include "cc/output/begin_frame_args.h"
#include "cc/test/ordered_simple_task_runner.h"
-#include "components/scheduler/child/nestable_task_runner_for_test.h"
-#include "components/scheduler/child/scheduler_message_loop_delegate.h"
-#include "components/scheduler/child/test_time_source.h"
+#include "components/scheduler/base/test_time_source.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate_for_test.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -126,34 +126,72 @@ void PostingYieldingTestTask(RendererSchedulerImpl* scheduler,
*should_yield_after = scheduler->ShouldYieldForHighPriorityWork();
}
+enum class SimulateInputType {
+ None,
+ TouchStart,
+ TouchEnd,
+ GestureScrollBegin,
+ GestureScrollEnd
+};
+
void AnticipationTestTask(RendererSchedulerImpl* scheduler,
- bool simulate_input,
+ SimulateInputType simulate_input,
bool* is_anticipated_before,
bool* is_anticipated_after) {
*is_anticipated_before = scheduler->IsHighPriorityWorkAnticipated();
- if (simulate_input) {
- scheduler->DidHandleInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureFlingStart),
- RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
+ switch (simulate_input) {
+ case SimulateInputType::None:
+ break;
+
+ case SimulateInputType::TouchStart:
+ scheduler->DidHandleInputEventOnCompositorThread(
+ FakeInputEvent(blink::WebInputEvent::TouchStart),
+ RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
+ break;
+
+ case SimulateInputType::TouchEnd:
+ scheduler->DidHandleInputEventOnCompositorThread(
+ FakeInputEvent(blink::WebInputEvent::TouchEnd),
+ RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
+ break;
+
+ case SimulateInputType::GestureScrollBegin:
+ scheduler->DidHandleInputEventOnCompositorThread(
+ FakeInputEvent(blink::WebInputEvent::GestureScrollBegin),
+ RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
+ break;
+
+ case SimulateInputType::GestureScrollEnd:
+ scheduler->DidHandleInputEventOnCompositorThread(
+ FakeInputEvent(blink::WebInputEvent::GestureScrollEnd),
+ RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
+ break;
}
*is_anticipated_after = scheduler->IsHighPriorityWorkAnticipated();
}
+
}; // namespace
class RendererSchedulerImplForTest : public RendererSchedulerImpl {
public:
using RendererSchedulerImpl::OnIdlePeriodEnded;
using RendererSchedulerImpl::OnIdlePeriodStarted;
- using RendererSchedulerImpl::Policy;
- using RendererSchedulerImpl::PolicyToString;
RendererSchedulerImplForTest(
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner)
: RendererSchedulerImpl(main_task_runner), update_policy_count_(0) {}
void UpdatePolicyLocked(UpdateType update_type) override {
update_policy_count_++;
RendererSchedulerImpl::UpdatePolicyLocked(update_type);
+
+ std::string use_case =
+ RendererScheduler::UseCaseToString(MainThreadOnly().current_use_case);
+ if (MainThreadOnly().touchstart_expected_soon) {
+ use_cases_.push_back(use_case + " scroll expected");
+ } else {
+ use_cases_.push_back(use_case);
+ }
}
void EnsureUrgentPolicyUpdatePostedOnMainThread() {
@@ -168,21 +206,22 @@ class RendererSchedulerImplForTest : public RendererSchedulerImpl {
bool BeginMainFrameOnCriticalPath() {
base::AutoLock lock(any_thread_lock_);
- return AnyThread().begin_main_frame_on_critical_path_;
+ return AnyThread().begin_main_frame_on_critical_path;
}
int update_policy_count_;
+ std::vector<std::string> use_cases_;
};
// Lets gtest print human readable Policy values.
::std::ostream& operator<<(::std::ostream& os,
- const RendererSchedulerImplForTest::Policy& policy) {
- return os << RendererSchedulerImplForTest::PolicyToString(policy);
+ const RendererScheduler::UseCase& use_case) {
+ return os << RendererScheduler::UseCaseToString(use_case);
}
class RendererSchedulerImplTest : public testing::Test {
public:
- using Policy = RendererSchedulerImpl::Policy;
+ using UseCase = RendererSchedulerImpl::UseCase;
RendererSchedulerImplTest() : clock_(new base::SimpleTestTickClock()) {
clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
@@ -197,16 +236,16 @@ class RendererSchedulerImplTest : public testing::Test {
void SetUp() override {
if (message_loop_) {
- nestable_task_runner_ =
- SchedulerMessageLoopDelegate::Create(message_loop_.get());
+ main_task_runner_ =
+ SchedulerTaskRunnerDelegateImpl::Create(message_loop_.get());
} else {
mock_task_runner_ = make_scoped_refptr(
new cc::OrderedSimpleTaskRunner(clock_.get(), false));
- nestable_task_runner_ =
- NestableTaskRunnerForTest::Create(mock_task_runner_);
+ main_task_runner_ =
+ SchedulerTaskRunnerDelegateForTest::Create(mock_task_runner_);
}
- Initialize(make_scoped_ptr(
- new RendererSchedulerImplForTest(nestable_task_runner_)));
+ Initialize(
+ make_scoped_ptr(new RendererSchedulerImplForTest(main_task_runner_)));
}
void Initialize(scoped_ptr<RendererSchedulerImplForTest> scheduler) {
@@ -222,6 +261,11 @@ class RendererSchedulerImplTest : public testing::Test {
->GetTaskQueueManagerForTesting()
->SetTimeSourceForTesting(
make_scoped_ptr(new TestTimeSource(clock_.get())));
+ scheduler_->GetLoadingTaskCostEstimatorForTesting()
+ ->SetTimeSourceForTesting(
+ make_scoped_ptr(new TestTimeSource(clock_.get())));
+ scheduler_->GetTimerTaskCostEstimatorForTesting()->SetTimeSourceForTesting(
+ make_scoped_ptr(new TestTimeSource(clock_.get())));
}
void TearDown() override {
@@ -248,16 +292,76 @@ class RendererSchedulerImplTest : public testing::Test {
}
void DoMainFrame() {
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
+ cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
+ base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL);
+ begin_frame_args.on_critical_path = false;
+ scheduler_->WillBeginFrame(begin_frame_args);
scheduler_->DidCommitFrameToCompositor();
}
+ void ForceMainThreadScrollingUseCase() {
+ cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create(
+ BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
+ base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL);
+ begin_frame_args.on_critical_path = true;
+ scheduler_->WillBeginFrame(begin_frame_args);
+ }
+
+ void ForceTouchStartToBeExpectedSoon() {
+ scheduler_->DidHandleInputEventOnCompositorThread(
+ FakeInputEvent(blink::WebInputEvent::GestureScrollEnd),
+ RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
+ clock_->Advance(priority_escalation_after_input_duration() * 2);
+ scheduler_->ForceUpdatePolicy();
+ }
+
+ void SimulateExpensiveTasks(
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
+ // RunUntilIdle won't actually run all of the SimpleTestTickClock::Advance
+ // tasks unless we set AutoAdvanceNow to true :/
+ mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
+
+ // Simulate a bunch of expensive tasks
+ for (int i = 0; i < 10; i++) {
+ task_runner->PostTask(FROM_HERE,
+ base::Bind(&base::SimpleTestTickClock::Advance,
+ base::Unretained(clock_.get()),
+ base::TimeDelta::FromMilliseconds(500)));
+ }
+
+ RunUntilIdle();
+
+ // Switch back to not auto-advancing because we want to be in control of
+ // when time advances.
+ mock_task_runner_->SetAutoAdvanceNowToPendingTasks(false);
+ }
+
void EnableIdleTasks() { DoMainFrame(); }
- Policy CurrentPolicy() {
- return scheduler_->MainThreadOnly().current_policy_;
+ UseCase CurrentUseCase() {
+ return scheduler_->MainThreadOnly().current_use_case;
+ }
+
+ UseCase ForceUpdatePolicyAndGetCurrentUseCase() {
+ scheduler_->ForceUpdatePolicy();
+ return scheduler_->MainThreadOnly().current_use_case;
+ }
+
+ bool TouchStartExpectedSoon() {
+ return scheduler_->MainThreadOnly().touchstart_expected_soon;
+ }
+
+ bool HaveSeenABeginMainframe() {
+ return scheduler_->MainThreadOnly().have_seen_a_begin_main_frame;
+ }
+
+ bool LoadingTasksSeemExpensive() {
+ return scheduler_->MainThreadOnly().loading_tasks_seem_expensive;
+ }
+
+ bool TimerTasksSeemExpensive() {
+ return scheduler_->MainThreadOnly().timer_tasks_seem_expensive;
}
// Helper for posting several tasks of specific types. |task_descriptor| is a
@@ -305,7 +409,12 @@ class RendererSchedulerImplTest : public testing::Test {
protected:
static base::TimeDelta priority_escalation_after_input_duration() {
return base::TimeDelta::FromMilliseconds(
- RendererSchedulerImpl::kPriorityEscalationAfterInputMillis);
+ UserModel::kGestureEstimationLimitMillis);
+ }
+
+ static base::TimeDelta subsequent_input_expected_after_input_duration() {
+ return base::TimeDelta::FromMilliseconds(
+ UserModel::kExpectSubsequentGestureMillis);
}
static base::TimeDelta maximum_idle_period_duration() {
@@ -323,6 +432,11 @@ class RendererSchedulerImplTest : public testing::Test {
RendererSchedulerImpl::kIdlePeriodStarvationThresholdMillis);
}
+ static base::TimeDelta suspend_timers_when_backgrounded_delay() {
+ return base::TimeDelta::FromMilliseconds(
+ RendererSchedulerImpl::kSuspendTimersWhenBackgroundedDelayMillis);
+ }
+
template <typename E>
static void CallForEachEnumValue(E first,
E last,
@@ -333,18 +447,11 @@ class RendererSchedulerImplTest : public testing::Test {
}
}
- static void CheckAllTaskQueueIdToString() {
- CallForEachEnumValue<RendererSchedulerImpl::QueueId>(
- RendererSchedulerImpl::FIRST_QUEUE_ID,
- RendererSchedulerImpl::TASK_QUEUE_COUNT,
- &RendererSchedulerImpl::TaskQueueIdToString);
- }
-
- static void CheckAllPolicyToString() {
- CallForEachEnumValue<RendererSchedulerImpl::Policy>(
- RendererSchedulerImpl::Policy::FIRST_POLICY,
- RendererSchedulerImpl::Policy::POLICY_COUNT,
- &RendererSchedulerImpl::PolicyToString);
+ static void CheckAllUseCaseToString() {
+ CallForEachEnumValue<RendererSchedulerImpl::UseCase>(
+ RendererSchedulerImpl::UseCase::FIRST_USE_CASE,
+ RendererSchedulerImpl::UseCase::USE_CASE_COUNT,
+ &RendererSchedulerImpl::UseCaseToString);
}
scoped_ptr<base::SimpleTestTickClock> clock_;
@@ -352,7 +459,7 @@ class RendererSchedulerImplTest : public testing::Test {
scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
scoped_ptr<base::MessageLoop> message_loop_;
- scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
+ scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner_;
scoped_ptr<RendererSchedulerImplForTest> scheduler_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
@@ -578,6 +685,7 @@ TEST_F(RendererSchedulerImplTest, TestDefaultPolicy) {
testing::ElementsAre(std::string("L1"), std::string("D1"),
std::string("C1"), std::string("D2"),
std::string("C2"), std::string("I1")));
+ EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase());
}
TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_CompositorHandlesInput) {
@@ -590,9 +698,10 @@ TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_CompositorHandlesInput) {
EnableIdleTasks();
RunUntilIdle();
EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("L1"), std::string("D1"),
- std::string("D2"), std::string("I1")));
+ testing::ElementsAre(std::string("L1"), std::string("D1"),
+ std::string("C1"), std::string("D2"),
+ std::string("C2"), std::string("I1")));
+ EXPECT_EQ(RendererScheduler::UseCase::COMPOSITOR_GESTURE, CurrentUseCase());
}
TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_MainThreadHandlesInput) {
@@ -605,9 +714,10 @@ TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_MainThreadHandlesInput) {
EnableIdleTasks();
RunUntilIdle();
EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("L1"), std::string("D1"),
- std::string("D2"), std::string("I1")));
+ testing::ElementsAre(std::string("L1"), std::string("D1"),
+ std::string("C1"), std::string("D2"),
+ std::string("C2"), std::string("I1")));
+ EXPECT_EQ(RendererScheduler::UseCase::COMPOSITOR_GESTURE, CurrentUseCase());
scheduler_->DidHandleInputEventOnMainThread(
FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
}
@@ -620,53 +730,56 @@ TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) {
EnableIdleTasks();
RunUntilIdle();
EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2"),
+ testing::ElementsAre(std::string("D1"), std::string("C1"),
+ std::string("D2"), std::string("C2"),
std::string("I1")));
+ EXPECT_EQ(RendererScheduler::UseCase::COMPOSITOR_GESTURE, CurrentUseCase());
}
-TEST_F(RendererSchedulerImplTest,
- TestCompositorPolicy_TimersOnlyRunWhenIdle_MainThreadOnCriticalPath) {
+// TODO(skyostil): Re-enable once timer blocking is re-enabled.
+TEST_F(
+ RendererSchedulerImplTest,
+ DISABLED_TestCompositorPolicy_ExpensiveTimersDontRunWhenMainThreadOnCriticalPath) {
std::vector<std::string> run_order;
+
+ SimulateExpensiveTasks(timer_task_runner_);
+
+ // Timers should now be disabled during main thread user user interactions.
PostTestTasks(&run_order, "C1 T1");
+ // Trigger main_thread_gesture UseCase
scheduler_->DidAnimateForInputOnCompositorThread();
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
+ cc::BeginFrameArgs begin_frame_args1 = cc::BeginFrameArgs::Create(
BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL));
- scheduler_->DidCommitFrameToCompositor(); // Starts Idle Period
+ base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL);
+ begin_frame_args1.on_critical_path = true;
+ scheduler_->WillBeginFrame(begin_frame_args1);
RunUntilIdle();
+ EXPECT_EQ(RendererScheduler::UseCase::MAIN_THREAD_GESTURE, CurrentUseCase());
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("T1")));
-
- // End the idle period.
- clock_->Advance(base::TimeDelta::FromMilliseconds(500));
- scheduler_->DidAnimateForInputOnCompositorThread();
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL));
+ EXPECT_THAT(run_order, testing::ElementsAre(std::string("C1")));
+ clock_->Advance(subsequent_input_expected_after_input_duration() * 2);
run_order.clear();
- PostTestTasks(&run_order, "C1 T1");
RunUntilIdle();
-
- EXPECT_THAT(run_order, testing::ElementsAre(std::string("C1")));
+ EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase());
+ EXPECT_THAT(run_order, testing::ElementsAre(std::string("T1")));
}
-TEST_F(RendererSchedulerImplTest,
- TestCompositorPolicy_TimersAlwaysRunIfNoRecentIdlePeriod) {
+TEST_F(RendererSchedulerImplTest, Navigation_ResetsTaskCostEstimations) {
std::vector<std::string> run_order;
- PostTestTasks(&run_order, "C1 T1");
- // Simulate no recent idle period.
- clock_->Advance(idle_period_starvation_threshold() * 2);
+ SimulateExpensiveTasks(timer_task_runner_);
+ scheduler_->OnNavigationStarted();
+ PostTestTasks(&run_order, "C1 T1");
scheduler_->DidAnimateForInputOnCompositorThread();
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
+ cc::BeginFrameArgs begin_frame_args1 = cc::BeginFrameArgs::Create(
BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL));
-
+ base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL);
+ begin_frame_args1.on_critical_path = true;
+ scheduler_->WillBeginFrame(begin_frame_args1);
+ scheduler_->DidCommitFrameToCompositor(); // Starts Idle Period
RunUntilIdle();
EXPECT_THAT(run_order,
@@ -722,8 +835,10 @@ TEST_F(RendererSchedulerImplTest, TestTouchstartPolicy_Compositor) {
testing::ElementsAre(std::string("C1"), std::string("C2"),
std::string("D1"), std::string("D2")));
- // Meta events like TapDown/FlingCancel shouldn't affect the priority.
+ // Animation or meta events like TapDown/FlingCancel shouldn't affect the
+ // priority.
run_order.clear();
+ scheduler_->DidAnimateForInputOnCompositorThread();
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::GestureFlingCancel),
RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
@@ -793,30 +908,38 @@ TEST_F(RendererSchedulerImplTest, TestTouchstartPolicy_MainThread) {
std::string("T2")));
}
-TEST_F(RendererSchedulerImplTest, LoadingPriorityPolicy) {
+// TODO(alexclarke): Reenable once we've reinstaed the Loading UseCase.
+TEST_F(RendererSchedulerImplTest, DISABLED_LoadingUseCase) {
std::vector<std::string> run_order;
- PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
+ PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2");
- scheduler_->OnPageLoadStarted();
+ scheduler_->OnNavigationStarted();
EnableIdleTasks();
RunUntilIdle();
- // In loading policy compositor tasks are best effort and should be run last.
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("L1"), std::string("D1"),
- std::string("D2"), std::string("I1"),
- std::string("C1"), std::string("C2")));
- // Advance 1.5s and try again, the loading policy should have ended and the
- // task order should return to normal.
- clock_->Advance(base::TimeDelta::FromMilliseconds(1500));
+ // In loading policy, loading tasks are prioritized other others.
+ std::string loading_policy_expected[] = {
+ std::string("D1"), std::string("L1"), std::string("D2"),
+ std::string("L2"), std::string("C1"), std::string("T1"),
+ std::string("C2"), std::string("T2"), std::string("I1")};
+ EXPECT_THAT(run_order, testing::ElementsAreArray(loading_policy_expected));
+ EXPECT_EQ(RendererScheduler::UseCase::LOADING, CurrentUseCase());
+
+ // Advance 15s and try again, the loading policy should have ended and the
+ // task order should return to the NONE use case where loading tasks are no
+ // longer prioritized.
+ clock_->Advance(base::TimeDelta::FromMilliseconds(150000));
run_order.clear();
- PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
+ PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2");
EnableIdleTasks();
RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("L1"), std::string("D1"),
- std::string("C1"), std::string("D2"),
- std::string("C2"), std::string("I1")));
+
+ std::string default_order_expected[] = {
+ std::string("D1"), std::string("C1"), std::string("T1"),
+ std::string("L1"), std::string("D2"), std::string("C2"),
+ std::string("T2"), std::string("L2"), std::string("I1")};
+ EXPECT_THAT(run_order, testing::ElementsAreArray(default_order_expected));
+ EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase());
}
TEST_F(RendererSchedulerImplTest,
@@ -824,12 +947,14 @@ TEST_F(RendererSchedulerImplTest,
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
+ ForceMainThreadScrollingUseCase();
+ scheduler_->DidCommitFrameToCompositor(); // Enable Idle tasks.
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::MouseMove),
RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
- EnableIdleTasks();
RunUntilIdle();
// Note compositor tasks are not prioritized.
+ EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase());
EXPECT_THAT(run_order,
testing::ElementsAre(std::string("D1"), std::string("C1"),
std::string("D2"), std::string("C2"),
@@ -841,18 +966,18 @@ TEST_F(RendererSchedulerImplTest,
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
+ ForceMainThreadScrollingUseCase();
+ scheduler_->DidCommitFrameToCompositor(); // Enable Idle tasks.
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::MouseMove),
RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
- EnableIdleTasks();
RunUntilIdle();
// Note compositor tasks are not prioritized.
+ EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase());
EXPECT_THAT(run_order,
testing::ElementsAre(std::string("D1"), std::string("C1"),
std::string("D2"), std::string("C2"),
std::string("I1")));
- scheduler_->DidHandleInputEventOnMainThread(
- FakeInputEvent(blink::WebInputEvent::MouseMove));
}
TEST_F(RendererSchedulerImplTest,
@@ -860,11 +985,12 @@ TEST_F(RendererSchedulerImplTest,
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
+ ForceMainThreadScrollingUseCase();
+ scheduler_->DidCommitFrameToCompositor(); // Enable Idle tasks.
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::MouseMove,
blink::WebInputEvent::LeftButtonDown),
RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
- EnableIdleTasks();
RunUntilIdle();
// Note compositor tasks are prioritized.
EXPECT_THAT(run_order,
@@ -878,11 +1004,12 @@ TEST_F(RendererSchedulerImplTest,
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
+ ForceMainThreadScrollingUseCase();
+ scheduler_->DidCommitFrameToCompositor(); // Enable Idle tasks.
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::MouseMove,
blink::WebInputEvent::LeftButtonDown),
RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
- EnableIdleTasks();
RunUntilIdle();
// Note compositor tasks are prioritized.
EXPECT_THAT(run_order,
@@ -897,10 +1024,11 @@ TEST_F(RendererSchedulerImplTest, EventConsumedOnCompositorThread_MouseWheel) {
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
+ ForceMainThreadScrollingUseCase();
+ scheduler_->DidCommitFrameToCompositor(); // Enable Idle tasks.
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::MouseWheel),
RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
- EnableIdleTasks();
RunUntilIdle();
// Note compositor tasks are prioritized.
EXPECT_THAT(run_order,
@@ -913,18 +1041,18 @@ TEST_F(RendererSchedulerImplTest, EventForwardedToMainThread_MouseWheel) {
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
+ ForceMainThreadScrollingUseCase();
+ scheduler_->DidCommitFrameToCompositor(); // Enable Idle tasks.
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::MouseWheel),
RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
- EnableIdleTasks();
RunUntilIdle();
// Note compositor tasks are prioritized.
EXPECT_THAT(run_order,
testing::ElementsAre(std::string("C1"), std::string("C2"),
std::string("D1"), std::string("D2"),
std::string("I1")));
- scheduler_->DidHandleInputEventOnMainThread(
- FakeInputEvent(blink::WebInputEvent::MouseWheel));
+ EXPECT_EQ(RendererScheduler::UseCase::MAIN_THREAD_GESTURE, CurrentUseCase());
}
TEST_F(RendererSchedulerImplTest,
@@ -932,16 +1060,18 @@ TEST_F(RendererSchedulerImplTest,
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
+ ForceMainThreadScrollingUseCase();
+ scheduler_->DidCommitFrameToCompositor(); // Enable Idle tasks.
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::KeyDown),
RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
- EnableIdleTasks();
RunUntilIdle();
// Note compositor tasks are not prioritized.
EXPECT_THAT(run_order,
testing::ElementsAre(std::string("D1"), std::string("C1"),
std::string("D2"), std::string("C2"),
std::string("I1")));
+ EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase());
}
TEST_F(RendererSchedulerImplTest,
@@ -949,22 +1079,28 @@ TEST_F(RendererSchedulerImplTest,
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
+ ForceMainThreadScrollingUseCase();
+ scheduler_->DidCommitFrameToCompositor(); // Enable Idle tasks.
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::KeyDown),
RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
- EnableIdleTasks();
RunUntilIdle();
// Note compositor tasks are not prioritized.
EXPECT_THAT(run_order,
testing::ElementsAre(std::string("D1"), std::string("C1"),
std::string("D2"), std::string("C2"),
std::string("I1")));
+ EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase());
+ // Note compositor tasks are not prioritized.
scheduler_->DidHandleInputEventOnMainThread(
FakeInputEvent(blink::WebInputEvent::KeyDown));
}
TEST_F(RendererSchedulerImplTest,
- TestCompositorPolicyDoesNotStarveDefaultTasks) {
+ TestMainthreadScrollingUseCaseDoesNotStarveDefaultTasks) {
+ ForceMainThreadScrollingUseCase();
+ scheduler_->DidCommitFrameToCompositor(); // Enable Idle tasks.
+
std::vector<std::string> run_order;
PostTestTasks(&run_order, "D1 C1");
@@ -986,52 +1122,28 @@ TEST_F(RendererSchedulerImplTest,
TEST_F(RendererSchedulerImplTest,
TestCompositorPolicyEnds_CompositorHandlesInput) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "D1 C1 D2 C2");
-
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::GestureFlingStart),
RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2")));
+ EXPECT_EQ(UseCase::COMPOSITOR_GESTURE,
+ ForceUpdatePolicyAndGetCurrentUseCase());
- run_order.clear();
clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
- PostTestTasks(&run_order, "D1 C1 D2 C2");
-
- // Compositor policy mode should have ended now that the clock has advanced.
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("D1"), std::string("C1"),
- std::string("D2"), std::string("C2")));
+ EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
}
TEST_F(RendererSchedulerImplTest,
TestCompositorPolicyEnds_MainThreadHandlesInput) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "D1 C1 D2 C2");
-
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::GestureFlingStart),
RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
scheduler_->DidHandleInputEventOnMainThread(
FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2")));
+ EXPECT_EQ(UseCase::COMPOSITOR_GESTURE,
+ ForceUpdatePolicyAndGetCurrentUseCase());
- run_order.clear();
clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
- PostTestTasks(&run_order, "D1 C1 D2 C2");
-
- // Compositor policy mode should have ended now that the clock has advanced.
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("D1"), std::string("C1"),
- std::string("D2"), std::string("C2")));
+ EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
}
TEST_F(RendererSchedulerImplTest, TestTouchstartPolicyEndsAfterTimeout) {
@@ -1095,22 +1207,33 @@ TEST_F(RendererSchedulerImplTest, TestIsHighPriorityWorkAnticipated) {
bool is_anticipated_before = false;
bool is_anticipated_after = false;
- bool simulate_input = false;
default_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input,
- &is_anticipated_before, &is_anticipated_after));
+ FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
+ SimulateInputType::None, &is_anticipated_before,
+ &is_anticipated_after));
RunUntilIdle();
// In its default state, without input receipt, the scheduler should indicate
// that no high-priority is anticipated.
EXPECT_FALSE(is_anticipated_before);
EXPECT_FALSE(is_anticipated_after);
- simulate_input = true;
+ default_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
+ SimulateInputType::TouchStart,
+ &is_anticipated_before, &is_anticipated_after));
+ bool dummy;
+ default_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
+ SimulateInputType::TouchEnd, &dummy, &dummy));
default_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input,
- &is_anticipated_before, &is_anticipated_after));
+ base::Bind(&AnticipationTestTask, scheduler_.get(),
+ SimulateInputType::GestureScrollBegin, &dummy, &dummy));
+ default_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&AnticipationTestTask, scheduler_.get(),
+ SimulateInputType::GestureScrollEnd, &dummy, &dummy));
+
RunUntilIdle();
// When input is received, the scheduler should indicate that high-priority
// work is anticipated.
@@ -1118,14 +1241,29 @@ TEST_F(RendererSchedulerImplTest, TestIsHighPriorityWorkAnticipated) {
EXPECT_TRUE(is_anticipated_after);
clock_->Advance(priority_escalation_after_input_duration() * 2);
- simulate_input = false;
default_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input,
- &is_anticipated_before, &is_anticipated_after));
- RunUntilIdle();
- // Without additional input, the scheduler should indicate that high-priority
- // work is no longer anticipated.
+ FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
+ SimulateInputType::None, &is_anticipated_before,
+ &is_anticipated_after));
+ RunUntilIdle();
+ // Without additional input, the scheduler should go into NONE
+ // use case but with scrolling expected where high-priority work is still
+ // anticipated.
+ EXPECT_EQ(UseCase::NONE, CurrentUseCase());
+ EXPECT_TRUE(TouchStartExpectedSoon());
+ EXPECT_TRUE(is_anticipated_before);
+ EXPECT_TRUE(is_anticipated_after);
+
+ clock_->Advance(subsequent_input_expected_after_input_duration() * 2);
+ default_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
+ SimulateInputType::None, &is_anticipated_before,
+ &is_anticipated_after));
+ RunUntilIdle();
+ // Eventually the scheduler should go into the default use case where
+ // high-priority work is no longer anticipated.
+ EXPECT_EQ(UseCase::NONE, CurrentUseCase());
+ EXPECT_FALSE(TouchStartExpectedSoon());
EXPECT_FALSE(is_anticipated_before);
EXPECT_FALSE(is_anticipated_after);
}
@@ -1134,6 +1272,8 @@ TEST_F(RendererSchedulerImplTest, TestShouldYield) {
bool should_yield_before = false;
bool should_yield_after = false;
+ ForceMainThreadScrollingUseCase();
+
default_task_runner_->PostTask(
FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
default_task_runner_, false, &should_yield_before,
@@ -1148,7 +1288,7 @@ TEST_F(RendererSchedulerImplTest, TestShouldYield) {
compositor_task_runner_, false,
&should_yield_before, &should_yield_after));
RunUntilIdle();
- // Posting while not in compositor priority shouldn't cause yielding.
+ // Posting while not mainthread scrolling shouldn't cause yielding.
EXPECT_FALSE(should_yield_before);
EXPECT_FALSE(should_yield_after);
@@ -1160,7 +1300,9 @@ TEST_F(RendererSchedulerImplTest, TestShouldYield) {
// We should be able to switch to compositor priority mid-task.
EXPECT_FALSE(should_yield_before);
EXPECT_TRUE(should_yield_after);
+}
+TEST_F(RendererSchedulerImplTest, TestShouldYield_TouchStart) {
// Receiving a touchstart should immediately trigger yielding, even if
// there's no immediately pending work in the compositor queue.
EXPECT_FALSE(scheduler_->ShouldYieldForHighPriorityWork());
@@ -1172,14 +1314,14 @@ TEST_F(RendererSchedulerImplTest, TestShouldYield) {
}
TEST_F(RendererSchedulerImplTest, SlowMainThreadInputEvent) {
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
+ EXPECT_EQ(UseCase::NONE, CurrentUseCase());
// An input event should bump us into input priority.
scheduler_->DidHandleInputEventOnCompositorThread(
FakeInputEvent(blink::WebInputEvent::GestureFlingStart),
RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
RunUntilIdle();
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
+ EXPECT_EQ(UseCase::COMPOSITOR_GESTURE, CurrentUseCase());
// Simulate the input event being queued for a very long time. The compositor
// task we post here represents the enqueued input task.
@@ -1190,12 +1332,12 @@ TEST_F(RendererSchedulerImplTest, SlowMainThreadInputEvent) {
// Even though we exceeded the input priority escalation period, we should
// still be in compositor priority since the input remains queued.
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
+ EXPECT_EQ(UseCase::COMPOSITOR_GESTURE, CurrentUseCase());
// After the escalation period ends we should go back into normal mode.
clock_->Advance(priority_escalation_after_input_duration() * 2);
RunUntilIdle();
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
+ EXPECT_EQ(UseCase::NONE, CurrentUseCase());
}
class RendererSchedulerImplWithMockSchedulerTest
@@ -1204,9 +1346,9 @@ class RendererSchedulerImplWithMockSchedulerTest
void SetUp() override {
mock_task_runner_ = make_scoped_refptr(
new cc::OrderedSimpleTaskRunner(clock_.get(), false));
- nestable_task_runner_ =
- NestableTaskRunnerForTest::Create(mock_task_runner_);
- mock_scheduler_ = new RendererSchedulerImplForTest(nestable_task_runner_);
+ main_task_runner_ =
+ SchedulerTaskRunnerDelegateForTest::Create(mock_task_runner_);
+ mock_scheduler_ = new RendererSchedulerImplForTest(main_task_runner_);
Initialize(make_scoped_ptr(mock_scheduler_));
}
@@ -1373,7 +1515,7 @@ TEST_F(RendererSchedulerImplWithMockSchedulerTest,
FakeInputEvent(blink::WebInputEvent::TouchStart),
RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
scheduler_->DidHandleInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchMove),
+ FakeInputEvent(blink::WebInputEvent::GestureScrollBegin),
RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
// We expect the first call to IsHighPriorityWorkAnticipated to be called
@@ -1394,14 +1536,19 @@ TEST_F(RendererSchedulerImplWithMockSchedulerTest,
scheduler_->DidHandleInputEventOnMainThread(
FakeInputEvent(blink::WebInputEvent::TouchStart));
scheduler_->DidHandleInputEventOnMainThread(
- FakeInputEvent(blink::WebInputEvent::TouchMove));
+ FakeInputEvent(blink::WebInputEvent::GestureScrollBegin));
EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
- RunUntilIdle();
// We expect both the urgent and the delayed updates to run in addition to the
- // earlier updated cause by IsHighPriorityWorkAnticipated.
- EXPECT_EQ(3, mock_scheduler_->update_policy_count_);
+ // earlier updated cause by IsHighPriorityWorkAnticipated, a final update
+ // transitions from 'not_scrolling scroll expected' to 'not_scrolling'.
+ RunUntilIdle();
+ EXPECT_THAT(mock_scheduler_->use_cases_,
+ testing::ElementsAre(std::string("compositor_gesture"),
+ std::string("compositor_gesture"),
+ std::string("none scroll expected"),
+ std::string("none")));
}
class RendererSchedulerImplWithMessageLoopTest
@@ -1756,12 +1903,8 @@ TEST_F(RendererSchedulerImplTest, MultipleSuspendsNeedMultipleResumes) {
testing::ElementsAre(std::string("T1"), std::string("T2")));
}
-TEST_F(RendererSchedulerImplTest, TaskQueueIdToString) {
- CheckAllTaskQueueIdToString();
-}
-
-TEST_F(RendererSchedulerImplTest, PolicyToString) {
- CheckAllTaskQueueIdToString();
+TEST_F(RendererSchedulerImplTest, UseCaseToString) {
+ CheckAllUseCaseToString();
}
TEST_F(RendererSchedulerImplTest, MismatchedDidHandleInputEventOnMainThread) {
@@ -1795,4 +1938,168 @@ TEST_F(RendererSchedulerImplTest, ShutdownPreventsPostingOfNewTasks) {
EXPECT_TRUE(run_order.empty());
}
+TEST_F(RendererSchedulerImplTest, TestRendererBackgroundedTimerSuspension) {
+ scheduler_->SetTimerQueueSuspensionWhenBackgroundedEnabled(true);
+
+ std::vector<std::string> run_order;
+ PostTestTasks(&run_order, "T1 T2");
+
+ // The background signal will not immediately suspend the timer queue.
+ scheduler_->OnRendererBackgrounded();
+ RunUntilIdle();
+ EXPECT_THAT(run_order,
+ testing::ElementsAre(std::string("T1"), std::string("T2")));
+
+ run_order.clear();
+ PostTestTasks(&run_order, "T3");
+ RunUntilIdle();
+ EXPECT_THAT(run_order, testing::ElementsAre(std::string("T3")));
+
+ // Advance the time until after the scheduled timer queue suspension.
+ run_order.clear();
+ clock_->Advance(suspend_timers_when_backgrounded_delay() +
+ base::TimeDelta::FromMilliseconds(10));
+ RunUntilIdle();
+ ASSERT_TRUE(run_order.empty());
+
+ // Timer tasks should be suspended until the foregrounded signal.
+ PostTestTasks(&run_order, "T4 T5");
+ RunUntilIdle();
+ EXPECT_TRUE(run_order.empty());
+
+ scheduler_->OnRendererForegrounded();
+ RunUntilIdle();
+ EXPECT_THAT(run_order,
+ testing::ElementsAre(std::string("T4"), std::string("T5")));
+
+ // Subsequent timer tasks should fire as usual.
+ run_order.clear();
+ PostTestTasks(&run_order, "T6");
+ RunUntilIdle();
+ EXPECT_THAT(run_order, testing::ElementsAre(std::string("T6")));
+}
+
+TEST_F(RendererSchedulerImplTest,
+ ExpensiveLoadingTasksNotBlockedTillFirstBeginMainFrame) {
+ std::vector<std::string> run_order;
+
+ SimulateExpensiveTasks(loading_task_runner_);
+ ForceTouchStartToBeExpectedSoon();
+ PostTestTasks(&run_order, "L1 D1");
+ RunUntilIdle();
+
+ EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
+ EXPECT_FALSE(HaveSeenABeginMainframe());
+ EXPECT_TRUE(LoadingTasksSeemExpensive());
+ EXPECT_FALSE(TimerTasksSeemExpensive());
+ EXPECT_TRUE(TouchStartExpectedSoon());
+ EXPECT_THAT(run_order,
+ testing::ElementsAre(std::string("L1"), std::string("D1")));
+
+ // Emit a BeginMainFrame, and the loading task should get blocked.
+ DoMainFrame();
+ run_order.clear();
+
+ PostTestTasks(&run_order, "L1 D1");
+ RunUntilIdle();
+
+ EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase());
+ EXPECT_TRUE(HaveSeenABeginMainframe());
+ EXPECT_TRUE(LoadingTasksSeemExpensive());
+ EXPECT_FALSE(TimerTasksSeemExpensive());
+ EXPECT_TRUE(TouchStartExpectedSoon());
+ EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
+}
+
+TEST_F(RendererSchedulerImplTest,
+ ExpensiveLoadingTasksNotBlockedIfNavigationExpected) {
+ std::vector<std::string> run_order;
+
+ DoMainFrame();
+ SimulateExpensiveTasks(loading_task_runner_);
+ ForceTouchStartToBeExpectedSoon();
+ scheduler_->AddPendingNavigation();
+
+ PostTestTasks(&run_order, "L1 D1");
+ RunUntilIdle();
+
+ EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
+ EXPECT_TRUE(HaveSeenABeginMainframe());
+ EXPECT_TRUE(LoadingTasksSeemExpensive());
+ EXPECT_FALSE(TimerTasksSeemExpensive());
+ EXPECT_TRUE(TouchStartExpectedSoon());
+ EXPECT_THAT(run_order,
+ testing::ElementsAre(std::string("L1"), std::string("D1")));
+
+ // After the nagigation has been cancelled, the expensive loading tasks should
+ // get blocked.
+ scheduler_->RemovePendingNavigation();
+ run_order.clear();
+
+ PostTestTasks(&run_order, "L1 D1");
+ RunUntilIdle();
+
+ EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase());
+ EXPECT_TRUE(HaveSeenABeginMainframe());
+ EXPECT_TRUE(LoadingTasksSeemExpensive());
+ EXPECT_FALSE(TimerTasksSeemExpensive());
+ EXPECT_TRUE(TouchStartExpectedSoon());
+ EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
+}
+
+TEST_F(
+ RendererSchedulerImplTest,
+ ExpensiveLoadingTasksNotBlockedIfNavigationExpected_MultipleNavigations) {
+ std::vector<std::string> run_order;
+
+ DoMainFrame();
+ SimulateExpensiveTasks(loading_task_runner_);
+ ForceTouchStartToBeExpectedSoon();
+ scheduler_->AddPendingNavigation();
+ scheduler_->AddPendingNavigation();
+
+ PostTestTasks(&run_order, "L1 D1");
+ RunUntilIdle();
+
+ EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
+ EXPECT_TRUE(HaveSeenABeginMainframe());
+ EXPECT_TRUE(LoadingTasksSeemExpensive());
+ EXPECT_FALSE(TimerTasksSeemExpensive());
+ EXPECT_TRUE(TouchStartExpectedSoon());
+ EXPECT_THAT(run_order,
+ testing::ElementsAre(std::string("L1"), std::string("D1")));
+
+
+ run_order.clear();
+ scheduler_->RemovePendingNavigation();
+ // Navigation task expected ref count non-zero so expensive tasks still not
+ // blocked.
+ PostTestTasks(&run_order, "L1 D1");
+ RunUntilIdle();
+
+ EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase());
+ EXPECT_TRUE(HaveSeenABeginMainframe());
+ EXPECT_TRUE(LoadingTasksSeemExpensive());
+ EXPECT_FALSE(TimerTasksSeemExpensive());
+ EXPECT_TRUE(TouchStartExpectedSoon());
+ EXPECT_THAT(run_order,
+ testing::ElementsAre(std::string("L1"), std::string("D1")));
+
+
+ run_order.clear();
+ scheduler_->RemovePendingNavigation();
+ // Navigation task expected ref count is now zero, the expensive loading tasks
+ // should get blocked.
+ PostTestTasks(&run_order, "L1 D1");
+ RunUntilIdle();
+
+ EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase());
+ EXPECT_TRUE(HaveSeenABeginMainframe());
+ EXPECT_TRUE(LoadingTasksSeemExpensive());
+ EXPECT_FALSE(TimerTasksSeemExpensive());
+ EXPECT_TRUE(TouchStartExpectedSoon());
+ EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
+}
+
+
} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/renderer_web_scheduler_impl.cc b/chromium/components/scheduler/renderer/renderer_web_scheduler_impl.cc
index c833b7005c8..05d1daf6443 100644
--- a/chromium/components/scheduler/renderer/renderer_web_scheduler_impl.cc
+++ b/chromium/components/scheduler/renderer/renderer_web_scheduler_impl.cc
@@ -4,8 +4,9 @@
#include "components/scheduler/renderer/renderer_web_scheduler_impl.h"
-#include "components/scheduler/child/task_queue.h"
+#include "components/scheduler/base/task_queue.h"
#include "components/scheduler/renderer/renderer_scheduler.h"
+#include "components/scheduler/renderer/web_frame_host_scheduler_impl.h"
namespace scheduler {
@@ -29,4 +30,21 @@ void RendererWebSchedulerImpl::resumeTimerQueue() {
renderer_scheduler_->ResumeTimerQueue();
}
+blink::WebFrameHostScheduler*
+RendererWebSchedulerImpl::createFrameHostScheduler() {
+ return new WebFrameHostSchedulerImpl(renderer_scheduler_);
+}
+
+void RendererWebSchedulerImpl::addPendingNavigation() {
+ renderer_scheduler_->AddPendingNavigation();
+}
+
+void RendererWebSchedulerImpl::removePendingNavigation() {
+ renderer_scheduler_->RemovePendingNavigation();
+}
+
+void RendererWebSchedulerImpl::onNavigationStarted() {
+ renderer_scheduler_->OnNavigationStarted();
+}
+
} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/renderer_web_scheduler_impl.h b/chromium/components/scheduler/renderer/renderer_web_scheduler_impl.h
index 1001ddae68e..1deececdee0 100644
--- a/chromium/components/scheduler/renderer/renderer_web_scheduler_impl.h
+++ b/chromium/components/scheduler/renderer/renderer_web_scheduler_impl.h
@@ -18,8 +18,12 @@ class SCHEDULER_EXPORT RendererWebSchedulerImpl : public WebSchedulerImpl {
~RendererWebSchedulerImpl() override;
// blink::WebScheduler implementation:
- virtual void suspendTimerQueue();
- virtual void resumeTimerQueue();
+ void suspendTimerQueue() override;
+ void resumeTimerQueue() override;
+ blink::WebFrameHostScheduler* createFrameHostScheduler() override;
+ void addPendingNavigation() override;
+ void removePendingNavigation() override;
+ void onNavigationStarted() override;
private:
RendererScheduler* renderer_scheduler_; // NOT OWNED
diff --git a/chromium/components/scheduler/renderer/task_cost_estimator.cc b/chromium/components/scheduler/renderer/task_cost_estimator.cc
new file mode 100644
index 00000000000..736c5878e5e
--- /dev/null
+++ b/chromium/components/scheduler/renderer/task_cost_estimator.cc
@@ -0,0 +1,47 @@
+// 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/scheduler/renderer/task_cost_estimator.h"
+
+#include "base/time/default_tick_clock.h"
+
+namespace scheduler {
+
+TaskCostEstimator::TaskCostEstimator(int sample_count,
+ double estimation_percentile)
+ : rolling_time_delta_history_(sample_count),
+ time_source_(new base::DefaultTickClock),
+ outstanding_task_count_(0),
+ estimation_percentile_(estimation_percentile) {}
+
+TaskCostEstimator::~TaskCostEstimator() {}
+
+void TaskCostEstimator::WillProcessTask(const base::PendingTask& pending_task) {
+ // Avoid measuring the duration in nested run loops.
+ if (++outstanding_task_count_ == 1)
+ task_start_time_ = time_source_->NowTicks();
+}
+
+void TaskCostEstimator::DidProcessTask(const base::PendingTask& pending_task) {
+ if (--outstanding_task_count_ == 0) {
+ base::TimeDelta duration = time_source_->NowTicks() - task_start_time_;
+ rolling_time_delta_history_.InsertSample(duration);
+
+ // TODO(skyostil): Should we do this less often?
+ expected_task_duration_ =
+ rolling_time_delta_history_.Percentile(estimation_percentile_);
+ }
+}
+
+void TaskCostEstimator::Clear() {
+ rolling_time_delta_history_.Clear();
+ expected_task_duration_ = base::TimeDelta();
+}
+
+void TaskCostEstimator::SetTimeSourceForTesting(
+ scoped_ptr<base::TickClock> time_source) {
+ time_source_ = time_source.Pass();
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/task_cost_estimator.h b/chromium/components/scheduler/renderer/task_cost_estimator.h
new file mode 100644
index 00000000000..ac46b03b882
--- /dev/null
+++ b/chromium/components/scheduler/renderer/task_cost_estimator.h
@@ -0,0 +1,51 @@
+// 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_SCHEDULER_RENDERER_TASK_COST_ESTIMATOR_H_
+#define COMPONENTS_SCHEDULER_RENDERER_TASK_COST_ESTIMATOR_H_
+
+#include "base/message_loop/message_loop.h"
+#include "base/time/time.h"
+#include "cc/base/rolling_time_delta_history.h"
+#include "components/scheduler/scheduler_export.h"
+
+namespace base {
+class TickClock;
+}
+
+namespace scheduler {
+
+// Estimates the cost of running tasks based on historical timing data.
+class SCHEDULER_EXPORT TaskCostEstimator
+ : public base::MessageLoop::TaskObserver {
+ public:
+ TaskCostEstimator(int sample_count, double estimation_percentile);
+ ~TaskCostEstimator() override;
+
+ base::TimeDelta expected_task_duration() const {
+ return expected_task_duration_;
+ }
+
+ // TaskObserver implementation:
+ void WillProcessTask(const base::PendingTask& pending_task) override;
+ void DidProcessTask(const base::PendingTask& pending_task) override;
+
+ void Clear();
+
+ void SetTimeSourceForTesting(scoped_ptr<base::TickClock> time_source);
+
+ private:
+ cc::RollingTimeDeltaHistory rolling_time_delta_history_;
+ scoped_ptr<base::TickClock> time_source_;
+ int outstanding_task_count_;
+ double estimation_percentile_;
+ base::TimeTicks task_start_time_;
+ base::TimeDelta expected_task_duration_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskCostEstimator);
+};
+
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_RENDERER_TASK_COST_ESTIMATOR_H_
diff --git a/chromium/components/scheduler/renderer/task_cost_estimator_unittest.cc b/chromium/components/scheduler/renderer/task_cost_estimator_unittest.cc
new file mode 100644
index 00000000000..5f3fe8a5d47
--- /dev/null
+++ b/chromium/components/scheduler/renderer/task_cost_estimator_unittest.cc
@@ -0,0 +1,75 @@
+// 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 "base/test/simple_test_tick_clock.h"
+#include "components/scheduler/base/test_time_source.h"
+#include "components/scheduler/renderer/task_cost_estimator.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace scheduler {
+
+class TaskCostEstimatorTest : public testing::Test {
+ public:
+ TaskCostEstimatorTest() {}
+ ~TaskCostEstimatorTest() override {}
+
+ void SetUp() override {}
+
+ base::SimpleTestTickClock clock_;
+};
+
+class TaskCostEstimatorForTest : public TaskCostEstimator {
+ public:
+ TaskCostEstimatorForTest(base::SimpleTestTickClock* clock,
+ int sample_count,
+ double estimation_percentile)
+ : TaskCostEstimator(sample_count, estimation_percentile) {
+ SetTimeSourceForTesting(make_scoped_ptr(new TestTimeSource(clock)));
+ }
+};
+
+TEST_F(TaskCostEstimatorTest, BasicEstimation) {
+ TaskCostEstimatorForTest estimator(&clock_, 1, 100);
+ base::PendingTask task(FROM_HERE, base::Closure());
+
+ estimator.WillProcessTask(task);
+ clock_.Advance(base::TimeDelta::FromMilliseconds(500));
+ estimator.DidProcessTask(task);
+
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(500),
+ estimator.expected_task_duration());
+}
+
+TEST_F(TaskCostEstimatorTest, Clear) {
+ TaskCostEstimatorForTest estimator(&clock_, 1, 100);
+ base::PendingTask task(FROM_HERE, base::Closure());
+
+ estimator.WillProcessTask(task);
+ clock_.Advance(base::TimeDelta::FromMilliseconds(500));
+ estimator.DidProcessTask(task);
+
+ estimator.Clear();
+
+ EXPECT_EQ(base::TimeDelta(), estimator.expected_task_duration());
+}
+
+TEST_F(TaskCostEstimatorTest, NestedRunLoop) {
+ TaskCostEstimatorForTest estimator(&clock_, 1, 100);
+ base::PendingTask task(FROM_HERE, base::Closure());
+
+ // Make sure we ignore the tasks inside the nested run loop.
+ estimator.WillProcessTask(task);
+ estimator.WillProcessTask(task);
+ clock_.Advance(base::TimeDelta::FromMilliseconds(500));
+ estimator.DidProcessTask(task);
+ clock_.Advance(base::TimeDelta::FromMilliseconds(500));
+ estimator.DidProcessTask(task);
+
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000),
+ estimator.expected_task_duration());
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/user_model.cc b/chromium/components/scheduler/renderer/user_model.cc
new file mode 100644
index 00000000000..81abada5985
--- /dev/null
+++ b/chromium/components/scheduler/renderer/user_model.cc
@@ -0,0 +1,110 @@
+// 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/scheduler/renderer/user_model.h"
+
+namespace scheduler {
+
+UserModel::UserModel() : pending_input_event_count_(0) {}
+UserModel::~UserModel() {}
+
+void UserModel::DidStartProcessingInputEvent(blink::WebInputEvent::Type type,
+ const base::TimeTicks now) {
+ last_input_signal_time_ = now;
+ if (type == blink::WebInputEvent::TouchStart ||
+ type == blink::WebInputEvent::GestureScrollBegin ||
+ type == blink::WebInputEvent::GesturePinchBegin) {
+ last_gesture_start_time_ = now;
+ }
+
+ // We need to track continuous gestures seperatly for scroll detection
+ // because taps should not be confused with scrolls.
+ if (type == blink::WebInputEvent::GestureScrollBegin ||
+ type == blink::WebInputEvent::GestureScrollEnd ||
+ type == blink::WebInputEvent::GestureScrollUpdate ||
+ type == blink::WebInputEvent::GestureFlingStart ||
+ type == blink::WebInputEvent::GestureFlingCancel ||
+ type == blink::WebInputEvent::GesturePinchBegin ||
+ type == blink::WebInputEvent::GesturePinchEnd ||
+ type == blink::WebInputEvent::GesturePinchUpdate) {
+ last_continuous_gesture_time_ = now;
+ }
+
+ pending_input_event_count_++;
+}
+
+void UserModel::DidFinishProcessingInputEvent(const base::TimeTicks now) {
+ last_input_signal_time_ = now;
+ if (pending_input_event_count_ > 0)
+ pending_input_event_count_--;
+}
+
+base::TimeDelta UserModel::TimeLeftInUserGesture(base::TimeTicks now) const {
+ base::TimeDelta escalated_priority_duration =
+ base::TimeDelta::FromMilliseconds(kGestureEstimationLimitMillis);
+
+ // If the input event is still pending, go into input prioritized policy and
+ // check again later.
+ if (pending_input_event_count_ > 0)
+ return escalated_priority_duration;
+ if (last_input_signal_time_.is_null() ||
+ last_input_signal_time_ + escalated_priority_duration < now) {
+ return base::TimeDelta();
+ }
+ return last_input_signal_time_ + escalated_priority_duration - now;
+}
+
+bool UserModel::IsGestureExpectedSoon(
+ RendererScheduler::UseCase use_case,
+ const base::TimeTicks now,
+ base::TimeDelta* prediction_valid_duration) const {
+ if (use_case == RendererScheduler::UseCase::NONE) {
+ // If we've scrolled recently then future scrolling is likely.
+ base::TimeDelta expect_subsequent_gesture_for =
+ base::TimeDelta::FromMilliseconds(kExpectSubsequentGestureMillis);
+ if (last_continuous_gesture_time_.is_null() ||
+ last_continuous_gesture_time_ + expect_subsequent_gesture_for <= now) {
+ return false;
+ }
+ *prediction_valid_duration =
+ last_continuous_gesture_time_ + expect_subsequent_gesture_for - now;
+ return true;
+ }
+
+ if (use_case == RendererScheduler::UseCase::COMPOSITOR_GESTURE ||
+ use_case == RendererScheduler::UseCase::MAIN_THREAD_GESTURE) {
+ // If we've only just started scrolling then, then initiating a subsequent
+ // gesture is unlikely.
+ base::TimeDelta minimum_typical_scroll_duration =
+ base::TimeDelta::FromMilliseconds(kMinimumTypicalScrollDurationMillis);
+ if (last_gesture_start_time_.is_null() ||
+ last_gesture_start_time_ + minimum_typical_scroll_duration <= now) {
+ return true;
+ }
+ *prediction_valid_duration =
+ last_gesture_start_time_ + minimum_typical_scroll_duration - now;
+ return false;
+ }
+ return false;
+}
+
+void UserModel::Reset() {
+ last_input_signal_time_ = base::TimeTicks();
+ last_gesture_start_time_ = base::TimeTicks();
+ last_continuous_gesture_time_ = base::TimeTicks();
+}
+
+void UserModel::AsValueInto(base::trace_event::TracedValue* state) const {
+ state->BeginDictionary("user_model");
+ state->SetInteger("pending_input_event_count", pending_input_event_count_);
+ state->SetDouble(
+ "last_input_signal_time",
+ (last_input_signal_time_ - base::TimeTicks()).InMillisecondsF());
+ state->SetDouble(
+ "last_touchstart_time",
+ (last_gesture_start_time_ - base::TimeTicks()).InMillisecondsF());
+ state->EndDictionary();
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/user_model.h b/chromium/components/scheduler/renderer/user_model.h
new file mode 100644
index 00000000000..4eea8b10f98
--- /dev/null
+++ b/chromium/components/scheduler/renderer/user_model.h
@@ -0,0 +1,69 @@
+// 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_SCHEDULER_RENDERER_USER_MODEL_H_
+#define COMPONENTS_SCHEDULER_RENDERER_USER_MODEL_H_
+
+#include "base/macros.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
+#include "components/scheduler/scheduler_export.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+
+namespace scheduler {
+
+class SCHEDULER_EXPORT UserModel {
+ public:
+ UserModel();
+ ~UserModel();
+
+ // Tells us that the system started processing an input event. Must be paired
+ // with a call to DidFinishProcessingInputEvent.
+ void DidStartProcessingInputEvent(blink::WebInputEvent::Type type,
+ const base::TimeTicks now);
+
+ // Tells us that the system finished processing an input event.
+ void DidFinishProcessingInputEvent(const base::TimeTicks now);
+
+ // Returns the estimated amount of time left in the current user gesture, to a
+ // maximum of |kGestureEstimationLimitMillis|. After that time has elapased
+ // this function should be called again.
+ base::TimeDelta TimeLeftInUserGesture(base::TimeTicks now) const;
+
+ // Tries to guess if a user gesture is expected soon. Currently this is
+ // very simple, but one day I hope to do something more sophisticated here.
+ // The prediction may change after |prediction_valid_duration| has elapsed.
+ bool IsGestureExpectedSoon(RendererScheduler::UseCase use_case,
+ const base::TimeTicks now,
+ base::TimeDelta* prediction_valid_duration) const;
+
+ void AsValueInto(base::trace_event::TracedValue* state) const;
+
+ // The time we should stay in a priority-escalated mode after an input event.
+ static const int kGestureEstimationLimitMillis = 100;
+
+ // TODO(alexclarke): Get a real number on actual data.
+ static const int kMinimumTypicalScrollDurationMillis = 500;
+
+ // We consider further gesture start events to be likely if the user has
+ // interacted with the device in the past two seconds.
+ // TODO(alexclarke): Get a real number based on actual data.
+ static const int kExpectSubsequentGestureMillis = 2000;
+
+ // Clears input signals.
+ void Reset();
+
+ private:
+ int pending_input_event_count_;
+ base::TimeTicks last_input_signal_time_;
+ base::TimeTicks last_gesture_start_time_;
+ base::TimeTicks last_continuous_gesture_time_; // Doesn't include Taps.
+
+ DISALLOW_COPY_AND_ASSIGN(UserModel);
+};
+
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_RENDERER_USER_MODEL_H_
diff --git a/chromium/components/scheduler/renderer/user_model_unittest.cc b/chromium/components/scheduler/renderer/user_model_unittest.cc
new file mode 100644
index 00000000000..18d2a46455f
--- /dev/null
+++ b/chromium/components/scheduler/renderer/user_model_unittest.cc
@@ -0,0 +1,298 @@
+// 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/scheduler/renderer/user_model.h"
+
+#include "base/test/simple_test_tick_clock.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace scheduler {
+
+class UserModelTest : public testing::Test {
+ public:
+ UserModelTest() {}
+ ~UserModelTest() override {}
+
+ void SetUp() override {
+ clock_.reset(new base::SimpleTestTickClock());
+ clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+
+ user_model_.reset(new UserModel());
+ }
+
+ protected:
+ static base::TimeDelta priority_escalation_after_input_duration() {
+ return base::TimeDelta::FromMilliseconds(
+ UserModel::kGestureEstimationLimitMillis);
+ }
+
+ static base::TimeDelta subsequent_input_expected_after_input_duration() {
+ return base::TimeDelta::FromMilliseconds(
+ UserModel::kExpectSubsequentGestureMillis);
+ }
+
+ static base::TimeDelta minimum_typical_scroll_duration_millis() {
+ return base::TimeDelta::FromMilliseconds(
+ UserModel::kMinimumTypicalScrollDurationMillis);
+ }
+
+ scoped_ptr<base::SimpleTestTickClock> clock_;
+ scoped_ptr<UserModel> user_model_;
+};
+
+TEST_F(UserModelTest, TimeLeftInUserGesture_NoInput) {
+ EXPECT_EQ(base::TimeDelta(),
+ user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
+}
+
+TEST_F(UserModelTest, TimeLeftInUserGesture_ImmediatelyAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::TouchStart, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+ EXPECT_EQ(priority_escalation_after_input_duration(),
+ user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
+}
+
+TEST_F(UserModelTest, TimeLeftInUserGesture_ShortlyAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::TouchStart, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+ base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
+ clock_->Advance(delta);
+ EXPECT_EQ(priority_escalation_after_input_duration() - delta,
+ user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
+}
+
+TEST_F(UserModelTest, TimeLeftInUserGesture_LongAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::TouchStart, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+ clock_->Advance(priority_escalation_after_input_duration() * 2);
+ EXPECT_EQ(base::TimeDelta(),
+ user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
+}
+
+TEST_F(UserModelTest, DidFinishProcessingInputEvent_Delayed) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::TouchStart, clock_->NowTicks());
+ clock_->Advance(priority_escalation_after_input_duration() * 10);
+
+ EXPECT_EQ(priority_escalation_after_input_duration(),
+ user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
+
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+ base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
+ clock_->Advance(delta);
+
+ EXPECT_EQ(priority_escalation_after_input_duration() - delta,
+ user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
+}
+
+TEST_F(UserModelTest, GestureExpectedSoon_UseCase_NONE_NoRecentInput) {
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_FALSE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::NONE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
+}
+
+TEST_F(UserModelTest, GestureExpectedSoon_UseCase_NONE_ImmediatelyAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::GestureScrollEnd, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_TRUE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::NONE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(subsequent_input_expected_after_input_duration(),
+ prediction_valid_duration);
+}
+
+TEST_F(UserModelTest, GestureExpectedSoon_UseCase_NONE_ShortlyAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::GestureScrollEnd, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
+ clock_->Advance(delta);
+
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_TRUE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::NONE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(subsequent_input_expected_after_input_duration() - delta,
+ prediction_valid_duration);
+}
+
+TEST_F(UserModelTest, GestureExpectedSoon_UseCase_NONE_LongAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::GestureScrollEnd, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+ clock_->Advance(subsequent_input_expected_after_input_duration() * 2);
+
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_FALSE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::NONE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
+}
+
+TEST_F(UserModelTest,
+ GestureExpectedSoon_COMPOSITOR_GESTURE_ImmediatelyAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::TouchStart, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_FALSE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::COMPOSITOR_GESTURE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(minimum_typical_scroll_duration_millis(),
+ prediction_valid_duration);
+}
+
+TEST_F(UserModelTest,
+ GestureExpectedSoon_COMPOSITOR_GESTURE_ShortlyAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::TouchStart, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
+ clock_->Advance(delta);
+
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_FALSE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::COMPOSITOR_GESTURE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(minimum_typical_scroll_duration_millis() - delta,
+ prediction_valid_duration);
+}
+
+TEST_F(UserModelTest, GestureExpectedSoon_COMPOSITOR_GESTURE_LongAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::TouchStart, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ clock_->Advance(minimum_typical_scroll_duration_millis() * 2);
+
+ base::TimeDelta prediction_valid_duration;
+ // Note this isn't a bug, the UseCase will change to NONE eventually so it's
+ // OK for this to always be true after minimum_typical_scroll_duration_millis
+ EXPECT_TRUE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::COMPOSITOR_GESTURE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
+}
+
+TEST_F(UserModelTest,
+ GestureExpectedSoon_MAIN_THREAD_GESTURE_ImmediatelyAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::TouchStart, clock_->NowTicks());
+
+ // DidFinishProcessingInputEvent is always a little bit delayed.
+ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(5));
+ clock_->Advance(delay);
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_FALSE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::MAIN_THREAD_GESTURE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(minimum_typical_scroll_duration_millis() - delay,
+ prediction_valid_duration);
+}
+
+TEST_F(UserModelTest,
+ GestureExpectedSoon_MAIN_THREAD_GESTURE_ShortlyAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::TouchStart, clock_->NowTicks());
+ // DidFinishProcessingInputEvent is always a little bit delayed.
+ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(5));
+ clock_->Advance(delay);
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
+ clock_->Advance(delta);
+
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_FALSE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::MAIN_THREAD_GESTURE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(minimum_typical_scroll_duration_millis() - delta - delay,
+ prediction_valid_duration);
+}
+
+TEST_F(UserModelTest, GestureExpectedSoon_MAIN_THREAD_GESTURE_LongAfterInput) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::TouchStart, clock_->NowTicks());
+
+ // DidFinishProcessingInputEvent is always a little bit delayed.
+ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(5));
+ clock_->Advance(delay);
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ clock_->Advance(minimum_typical_scroll_duration_millis() * 2);
+
+ base::TimeDelta prediction_valid_duration;
+ // Note this isn't a bug, the UseCase will change to NONE eventually so it's
+ // OK for this to always be true after minimum_typical_scroll_duration_millis
+ EXPECT_TRUE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::MAIN_THREAD_GESTURE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
+}
+
+TEST_F(UserModelTest,
+ GestureExpectedSoon_UseCase_NONE_ShortlyAfterInput_GestureScrollBegin) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::GestureScrollBegin, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
+ clock_->Advance(delta);
+
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_TRUE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::NONE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(subsequent_input_expected_after_input_duration() - delta,
+ prediction_valid_duration);
+}
+
+TEST_F(UserModelTest,
+ GestureExpectedSoon_UseCase_NONE_ShortlyAfterInput_GesturePinchBegin) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::GestureScrollBegin, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
+ clock_->Advance(delta);
+
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_TRUE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::NONE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(subsequent_input_expected_after_input_duration() - delta,
+ prediction_valid_duration);
+}
+
+TEST_F(UserModelTest,
+ GestureExpectedSoon_UseCase_NONE_ShortlyAfterInput_GestureTap) {
+ user_model_->DidStartProcessingInputEvent(
+ blink::WebInputEvent::Type::GestureTap, clock_->NowTicks());
+ user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
+
+ base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
+ clock_->Advance(delta);
+
+ base::TimeDelta prediction_valid_duration;
+ EXPECT_FALSE(user_model_->IsGestureExpectedSoon(
+ RendererScheduler::UseCase::NONE, clock_->NowTicks(),
+ &prediction_valid_duration));
+ EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/web_frame_host_scheduler_impl.cc b/chromium/components/scheduler/renderer/web_frame_host_scheduler_impl.cc
new file mode 100644
index 00000000000..2b44fdfb4c5
--- /dev/null
+++ b/chromium/components/scheduler/renderer/web_frame_host_scheduler_impl.cc
@@ -0,0 +1,39 @@
+// 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/scheduler/renderer/web_frame_host_scheduler_impl.h"
+
+#include "base/logging.h"
+#include "components/scheduler/renderer/web_frame_scheduler_impl.h"
+
+namespace scheduler {
+
+WebFrameHostSchedulerImpl::WebFrameHostSchedulerImpl(
+ RendererScheduler* render_scheduler)
+ : render_scheduler_(render_scheduler), background_(false) {}
+
+WebFrameHostSchedulerImpl::~WebFrameHostSchedulerImpl() {
+ DCHECK(frame_schedulers_.empty()) << "WebFrameHostSchedulerImpl should "
+ "outlive its WebFrameSchedulers";
+}
+
+void WebFrameHostSchedulerImpl::setPageInBackground(bool background) {
+ background_ = background;
+ // TODO(alexclarke): Do something with this flag.
+}
+
+blink::WebFrameScheduler* WebFrameHostSchedulerImpl::createFrameScheduler() {
+ WebFrameSchedulerImpl* frame_scheduler =
+ new WebFrameSchedulerImpl(render_scheduler_, this);
+ frame_schedulers_.insert(frame_scheduler);
+ return frame_scheduler;
+}
+
+void WebFrameHostSchedulerImpl::Unregister(
+ WebFrameSchedulerImpl* frame_scheduler) {
+ DCHECK(frame_schedulers_.find(frame_scheduler) != frame_schedulers_.end());
+ frame_schedulers_.erase(frame_scheduler);
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/web_frame_host_scheduler_impl.h b/chromium/components/scheduler/renderer/web_frame_host_scheduler_impl.h
new file mode 100644
index 00000000000..c23dcebf7a8
--- /dev/null
+++ b/chromium/components/scheduler/renderer/web_frame_host_scheduler_impl.h
@@ -0,0 +1,46 @@
+// 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_SCHEDULER_RENDERER_WEB_FRAME_HOST_SCHEDULER_IMPL_H_
+#define COMPONENTS_SCHEDULER_RENDERER_WEB_FRAME_HOST_SCHEDULER_IMPL_H_
+
+#include <set>
+
+#include "base/macros.h"
+#include "components/scheduler/scheduler_export.h"
+#include "third_party/WebKit/public/platform/WebFrameHostScheduler.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace scheduler {
+
+class RendererScheduler;
+class WebFrameSchedulerImpl;
+
+class SCHEDULER_EXPORT WebFrameHostSchedulerImpl
+ : public blink::WebFrameHostScheduler {
+ public:
+ explicit WebFrameHostSchedulerImpl(RendererScheduler* render_scheduler);
+
+ ~WebFrameHostSchedulerImpl() override;
+
+ // blink::WebFrameHostScheduler implementation:
+ virtual void setPageInBackground(bool background);
+ virtual blink::WebFrameScheduler* createFrameScheduler();
+
+ void Unregister(WebFrameSchedulerImpl* frame_scheduler);
+
+ private:
+ std::set<WebFrameSchedulerImpl*> frame_schedulers_;
+ RendererScheduler* render_scheduler_;
+ bool background_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebFrameHostSchedulerImpl);
+};
+
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_RENDERER_WEB_FRAME_HOST_SCHEDULER_IMPL_H_
diff --git a/chromium/components/scheduler/renderer/web_frame_scheduler_impl.cc b/chromium/components/scheduler/renderer/web_frame_scheduler_impl.cc
new file mode 100644
index 00000000000..b7bd1a618ce
--- /dev/null
+++ b/chromium/components/scheduler/renderer/web_frame_scheduler_impl.cc
@@ -0,0 +1,60 @@
+// 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/scheduler/renderer/web_frame_scheduler_impl.h"
+
+#include "components/scheduler/child/web_task_runner_impl.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
+#include "components/scheduler/renderer/web_frame_host_scheduler_impl.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+
+namespace scheduler {
+
+WebFrameSchedulerImpl::WebFrameSchedulerImpl(
+ RendererScheduler* render_scheduler,
+ WebFrameHostSchedulerImpl* parent_frame_host_scheduler)
+ : render_scheduler_(render_scheduler),
+ parent_frame_host_scheduler_(parent_frame_host_scheduler),
+ visible_(true) {}
+
+WebFrameSchedulerImpl::~WebFrameSchedulerImpl() {
+ if (loading_task_queue_.get())
+ loading_task_queue_->UnregisterTaskQueue();
+
+ if (timer_task_queue_.get())
+ timer_task_queue_->UnregisterTaskQueue();
+
+ parent_frame_host_scheduler_->Unregister(this);
+}
+
+void WebFrameSchedulerImpl::setFrameVisible(bool visible) {
+ visible_ = visible;
+ // TODO(alexclarke): Do something with this flag.
+}
+
+blink::WebTaskRunner* WebFrameSchedulerImpl::loadingTaskRunner() {
+ if (!loading_web_task_runner_) {
+ loading_task_queue_ =
+ render_scheduler_->NewLoadingTaskRunner("frame_loading_tq");
+ loading_web_task_runner_.reset(new WebTaskRunnerImpl(loading_task_queue_));
+ }
+ return loading_web_task_runner_.get();
+}
+
+blink::WebTaskRunner* WebFrameSchedulerImpl::timerTaskRunner() {
+ if (!timer_web_task_runner_) {
+ timer_task_queue_ = render_scheduler_->NewTimerTaskRunner("frame_timer_tq");
+ timer_web_task_runner_.reset(new WebTaskRunnerImpl(timer_task_queue_));
+ }
+ return timer_web_task_runner_.get();
+}
+
+void WebFrameSchedulerImpl::setFrameOrigin(
+ const blink::WebSecurityOrigin* origin) {
+ DCHECK(origin);
+ origin_ = *origin;
+ // TODO(skyostil): Associate the task queues with this origin.
+}
+
+} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/web_frame_scheduler_impl.h b/chromium/components/scheduler/renderer/web_frame_scheduler_impl.h
new file mode 100644
index 00000000000..2191cfd3ae2
--- /dev/null
+++ b/chromium/components/scheduler/renderer/web_frame_scheduler_impl.h
@@ -0,0 +1,54 @@
+// 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_SCHEDULER_RENDERER_WEB_FRAME_SCHEDULER_IMPL_H_
+#define COMPONENTS_SCHEDULER_RENDERER_WEB_FRAME_SCHEDULER_IMPL_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/scheduler/scheduler_export.h"
+#include "third_party/WebKit/public/platform/WebFrameScheduler.h"
+#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace scheduler {
+
+class RendererScheduler;
+class TaskQueue;
+class WebFrameHostSchedulerImpl;
+class WebTaskRunnerImpl;
+
+class SCHEDULER_EXPORT WebFrameSchedulerImpl : public blink::WebFrameScheduler {
+ public:
+ WebFrameSchedulerImpl(RendererScheduler* render_scheduler,
+ WebFrameHostSchedulerImpl* parent_frame_host_scheduler);
+
+ ~WebFrameSchedulerImpl() override;
+
+ // blink::WebFrameScheduler implementation:
+ virtual void setFrameVisible(bool visible);
+ virtual blink::WebTaskRunner* loadingTaskRunner();
+ virtual blink::WebTaskRunner* timerTaskRunner();
+ virtual void setFrameOrigin(const blink::WebSecurityOrigin* origin);
+
+ private:
+ scoped_refptr<TaskQueue> loading_task_queue_;
+ scoped_refptr<TaskQueue> timer_task_queue_;
+ scoped_ptr<WebTaskRunnerImpl> loading_web_task_runner_;
+ scoped_ptr<WebTaskRunnerImpl> timer_web_task_runner_;
+ RendererScheduler* render_scheduler_; // NOT OWNED
+ WebFrameHostSchedulerImpl* parent_frame_host_scheduler_; // NOT OWNED
+ blink::WebSecurityOrigin origin_;
+ bool visible_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebFrameSchedulerImpl);
+};
+
+} // namespace scheduler
+
+#endif // COMPONENTS_SCHEDULER_RENDERER_WEB_FRAME_SCHEDULER_IMPL_H_
diff --git a/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc b/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc
index b7720b10edb..cd725b0efeb 100644
--- a/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc
+++ b/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc
@@ -4,7 +4,8 @@
#include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h"
-#include "components/scheduler/child/task_queue.h"
+#include "components/scheduler/base/task_queue.h"
+#include "components/scheduler/child/web_task_runner_impl.h"
#include "components/scheduler/renderer/renderer_scheduler.h"
#include "components/scheduler/renderer/renderer_web_scheduler_impl.h"
#include "third_party/WebKit/public/platform/WebTraceLocation.h"
@@ -17,8 +18,8 @@ WebThreadImplForRendererScheduler::WebThreadImplForRendererScheduler(
task_runner_(scheduler->DefaultTaskRunner()),
idle_task_runner_(scheduler->IdleTaskRunner()),
scheduler_(scheduler),
- thread_id_(base::PlatformThread::CurrentId()) {
-}
+ thread_id_(base::PlatformThread::CurrentId()),
+ web_task_runner_(new WebTaskRunnerImpl(scheduler->DefaultTaskRunner())) {}
WebThreadImplForRendererScheduler::~WebThreadImplForRendererScheduler() {
}
@@ -41,6 +42,10 @@ SingleThreadIdleTaskRunner* WebThreadImplForRendererScheduler::IdleTaskRunner()
return idle_task_runner_.get();
}
+blink::WebTaskRunner* WebThreadImplForRendererScheduler::taskRunner() {
+ return web_task_runner_.get();
+}
+
void WebThreadImplForRendererScheduler::AddTaskObserverInternal(
base::MessageLoop::TaskObserver* observer) {
scheduler_->AddTaskObserver(observer);
diff --git a/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h b/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h
index 104e466faa4..0c54c467f43 100644
--- a/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h
+++ b/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h
@@ -15,16 +15,18 @@ class WebScheduler;
namespace scheduler {
class RendererScheduler;
class WebSchedulerImpl;
+class WebTaskRunnerImpl;
class SCHEDULER_EXPORT WebThreadImplForRendererScheduler
: public WebThreadBase {
public:
explicit WebThreadImplForRendererScheduler(RendererScheduler* scheduler);
- virtual ~WebThreadImplForRendererScheduler();
+ ~WebThreadImplForRendererScheduler() override;
// blink::WebThread implementation.
- blink::WebScheduler* scheduler() const;
+ blink::WebScheduler* scheduler() const override;
blink::PlatformThreadId threadId() const override;
+ blink::WebTaskRunner* taskRunner() override;
// WebThreadBase implementation.
base::SingleThreadTaskRunner* TaskRunner() const override;
@@ -41,6 +43,7 @@ class SCHEDULER_EXPORT WebThreadImplForRendererScheduler
scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
RendererScheduler* scheduler_; // Not owned.
blink::PlatformThreadId thread_id_;
+ scoped_ptr<WebTaskRunnerImpl> web_task_runner_;
};
} // namespace scheduler
diff --git a/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc b/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
index d67c4b4eae1..9e3fbb2a941 100644
--- a/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
+++ b/chromium/components/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
@@ -7,10 +7,11 @@
#include "base/location.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
-#include "components/scheduler/child/scheduler_message_loop_delegate.h"
+#include "components/scheduler/child/scheduler_task_runner_delegate_impl.h"
#include "components/scheduler/renderer/renderer_scheduler_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebTaskRunner.h"
#include "third_party/WebKit/public/platform/WebTraceLocation.h"
namespace scheduler {
@@ -18,7 +19,7 @@ namespace {
const int kWorkBatchSize = 2;
-class MockTask : public blink::WebThread::Task {
+class MockTask : public blink::WebTaskRunner::Task {
public:
MOCK_METHOD0(run, void());
};
@@ -33,7 +34,7 @@ class MockTaskObserver : public blink::WebThread::TaskObserver {
class WebThreadImplForRendererSchedulerTest : public testing::Test {
public:
WebThreadImplForRendererSchedulerTest()
- : scheduler_(SchedulerMessageLoopDelegate::Create(&message_loop_)),
+ : scheduler_(SchedulerTaskRunnerDelegateImpl::Create(&message_loop_)),
default_task_runner_(scheduler_.DefaultTaskRunner()),
thread_(&scheduler_) {}
@@ -47,12 +48,6 @@ class WebThreadImplForRendererSchedulerTest : public testing::Test {
void TearDown() override { scheduler_.Shutdown(); }
protected:
- void EatDefaultTask(MockTaskObserver* observer) {
- // The scheduler posts one extra DoWork() task automatically.
- EXPECT_CALL(*observer, willProcessTask());
- EXPECT_CALL(*observer, didProcessTask());
- }
-
base::MessageLoop message_loop_;
RendererSchedulerImpl scheduler_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
@@ -71,11 +66,9 @@ TEST_F(WebThreadImplForRendererSchedulerTest, TestTaskObserver) {
EXPECT_CALL(observer, willProcessTask());
EXPECT_CALL(*task, run());
EXPECT_CALL(observer, didProcessTask());
-
- EatDefaultTask(&observer);
}
- thread_.postTask(blink::WebTraceLocation(), task.release());
+ thread_.taskRunner()->postTask(blink::WebTraceLocation(), task.release());
message_loop_.RunUntilIdle();
thread_.removeTaskObserver(&observer);
}
@@ -91,11 +84,9 @@ TEST_F(WebThreadImplForRendererSchedulerTest, TestWorkBatchWithOneTask) {
EXPECT_CALL(observer, willProcessTask());
EXPECT_CALL(*task, run());
EXPECT_CALL(observer, didProcessTask());
-
- EatDefaultTask(&observer);
}
- thread_.postTask(blink::WebTraceLocation(), task.release());
+ thread_.taskRunner()->postTask(blink::WebTraceLocation(), task.release());
message_loop_.RunUntilIdle();
thread_.removeTaskObserver(&observer);
}
@@ -116,12 +107,10 @@ TEST_F(WebThreadImplForRendererSchedulerTest, TestWorkBatchWithTwoTasks) {
EXPECT_CALL(observer, willProcessTask());
EXPECT_CALL(*task2, run());
EXPECT_CALL(observer, didProcessTask());
-
- EatDefaultTask(&observer);
}
- thread_.postTask(blink::WebTraceLocation(), task1.release());
- thread_.postTask(blink::WebTraceLocation(), task2.release());
+ thread_.taskRunner()->postTask(blink::WebTraceLocation(), task1.release());
+ thread_.taskRunner()->postTask(blink::WebTraceLocation(), task2.release());
message_loop_.RunUntilIdle();
thread_.removeTaskObserver(&observer);
}
@@ -147,22 +136,20 @@ TEST_F(WebThreadImplForRendererSchedulerTest, TestWorkBatchWithThreeTasks) {
EXPECT_CALL(observer, willProcessTask());
EXPECT_CALL(*task3, run());
EXPECT_CALL(observer, didProcessTask());
-
- EatDefaultTask(&observer);
}
- thread_.postTask(blink::WebTraceLocation(), task1.release());
- thread_.postTask(blink::WebTraceLocation(), task2.release());
- thread_.postTask(blink::WebTraceLocation(), task3.release());
+ thread_.taskRunner()->postTask(blink::WebTraceLocation(), task1.release());
+ thread_.taskRunner()->postTask(blink::WebTraceLocation(), task2.release());
+ thread_.taskRunner()->postTask(blink::WebTraceLocation(), task3.release());
message_loop_.RunUntilIdle();
thread_.removeTaskObserver(&observer);
}
-class ExitRunLoopTask : public blink::WebThread::Task {
+class ExitRunLoopTask : public blink::WebTaskRunner::Task {
public:
ExitRunLoopTask(base::RunLoop* run_loop) : run_loop_(run_loop) {}
- virtual void run() { run_loop_->Quit(); }
+ void run() override { run_loop_->Quit(); }
private:
base::RunLoop* run_loop_;
@@ -172,7 +159,8 @@ void EnterRunLoop(base::MessageLoop* message_loop, blink::WebThread* thread) {
// Note: WebThreads do not support nested run loops, which is why we use a
// run loop directly.
base::RunLoop run_loop;
- thread->postTask(blink::WebTraceLocation(), new ExitRunLoopTask(&run_loop));
+ thread->taskRunner()->postTask(blink::WebTraceLocation(),
+ new ExitRunLoopTask(&run_loop));
message_loop->SetNestableTasksAllowed(true);
run_loop.Run();
}
@@ -193,8 +181,6 @@ TEST_F(WebThreadImplForRendererSchedulerTest, TestNestedRunLoop) {
// A final callback for EnterRunLoop.
EXPECT_CALL(observer, didProcessTask());
-
- EatDefaultTask(&observer);
}
message_loop_.task_runner()->PostTask(
diff --git a/chromium/components/scheduler/scheduler.gyp b/chromium/components/scheduler/scheduler.gyp
index cffc0726e6e..aa9a15a171c 100644
--- a/chromium/components/scheduler/scheduler.gyp
+++ b/chromium/components/scheduler/scheduler.gyp
@@ -14,22 +14,10 @@
],
'targets': [
{
- # GN version: //components/scheduler:common
- 'target_name': 'scheduler_common',
- 'type': 'static_library',
- 'include_dirs': [
- '../..',
- ],
- 'sources': [
- '<@(scheduler_common_sources)',
- ],
- },
- {
# GN version: //components/scheduler:scheduler
'target_name': 'scheduler',
'type': '<(component)',
'dependencies': [
- 'scheduler_common',
'../../base/base.gyp:base',
'../../cc/cc.gyp:cc',
'../../third_party/WebKit/public/blink.gyp:blink',
diff --git a/chromium/components/scheduler/scheduler.gypi b/chromium/components/scheduler/scheduler.gypi
index 9f8e9704651..13ca288e6c3 100644
--- a/chromium/components/scheduler/scheduler.gypi
+++ b/chromium/components/scheduler/scheduler.gypi
@@ -4,39 +4,38 @@
{
'variables': {
- 'scheduler_common_sources': [
- 'common/scheduler_switches.cc',
- 'common/scheduler_switches.h',
- ],
'scheduler_sources': [
- 'child/cancelable_closure_holder.cc',
- 'child/cancelable_closure_holder.h',
+ 'base/cancelable_closure_holder.cc',
+ 'base/cancelable_closure_holder.h',
+ 'base/lazy_now.cc',
+ 'base/lazy_now.h',
+ 'base/nestable_single_thread_task_runner.h',
+ 'base/task_queue.cc',
+ 'base/task_queue.h',
+ 'base/task_queue_impl.cc',
+ 'base/task_queue_impl.h',
+ 'base/task_queue_manager.cc',
+ 'base/task_queue_manager.h',
+ 'base/task_queue_selector.cc',
+ 'base/task_queue_selector.h',
+ 'base/task_queue_sets.cc',
+ 'base/task_queue_sets.h',
+ 'base/pollable_thread_safe_flag.cc',
+ 'base/pollable_thread_safe_flag.h',
'child/child_scheduler.h',
'child/idle_helper.cc',
'child/idle_helper.h',
- 'child/nestable_single_thread_task_runner.h',
- 'child/null_idle_task_runner.cc',
- 'child/null_idle_task_runner.h',
- 'child/null_task_queue.cc',
- 'child/null_task_queue.h',
- 'child/null_worker_scheduler.cc',
- 'child/null_worker_scheduler.h',
- 'child/pollable_thread_safe_flag.cc',
- 'child/pollable_thread_safe_flag.h',
- 'child/prioritizing_task_queue_selector.cc',
- 'child/prioritizing_task_queue_selector.h',
'child/scheduler_helper.cc',
'child/scheduler_helper.h',
- 'child/scheduler_message_loop_delegate.cc',
- 'child/scheduler_message_loop_delegate.h',
+ 'child/scheduler_task_runner_delegate.h',
+ 'child/scheduler_task_runner_delegate_impl.cc',
+ 'child/scheduler_task_runner_delegate_impl.h',
'child/single_thread_idle_task_runner.cc',
'child/single_thread_idle_task_runner.h',
- 'child/task_queue.h',
- 'child/task_queue_manager.cc',
- 'child/task_queue_manager.h',
- 'child/task_queue_selector.h',
'child/web_scheduler_impl.cc',
'child/web_scheduler_impl.h',
+ 'child/web_task_runner_impl.cc',
+ 'child/web_task_runner_impl.h',
'child/webthread_base.cc',
'child/webthread_base.h',
'child/webthread_impl_for_worker_scheduler.cc',
@@ -45,16 +44,24 @@
'child/worker_scheduler.h',
'child/worker_scheduler_impl.cc',
'child/worker_scheduler_impl.h',
+ 'ppapi/webthread_impl_for_ppapi.cc',
+ 'ppapi/webthread_impl_for_ppapi.h',
'renderer/deadline_task_runner.cc',
'renderer/deadline_task_runner.h',
- 'renderer/null_renderer_scheduler.cc',
- 'renderer/null_renderer_scheduler.h',
'renderer/renderer_scheduler.cc',
'renderer/renderer_scheduler.h',
'renderer/renderer_scheduler_impl.cc',
'renderer/renderer_scheduler_impl.h',
'renderer/renderer_web_scheduler_impl.cc',
'renderer/renderer_web_scheduler_impl.h',
+ 'renderer/web_frame_host_scheduler_impl.cc',
+ 'renderer/web_frame_host_scheduler_impl.h',
+ 'renderer/web_frame_scheduler_impl.cc',
+ 'renderer/web_frame_scheduler_impl.h',
+ 'renderer/task_cost_estimator.cc',
+ 'renderer/task_cost_estimator.h',
+ 'renderer/user_model.cc',
+ 'renderer/user_model.h',
'renderer/webthread_impl_for_renderer_scheduler.cc',
'renderer/webthread_impl_for_renderer_scheduler.h',
'scheduler_export.h',
diff --git a/chromium/components/search.gypi b/chromium/components/search.gypi
index 8cb0fe71e0c..5c79aa708e3 100644
--- a/chromium/components/search.gypi
+++ b/chromium/components/search.gypi
@@ -8,7 +8,10 @@
'target_name': 'search',
'type': 'static_library',
'dependencies': [
- '../base/base.gyp:base'
+ '../base/base.gyp:base',
+ '../url/url.gyp:url_lib',
+ 'google_core_browser',
+ 'search_engines',
],
'include_dirs': [
'..',
diff --git a/chromium/components/search_engines.gypi b/chromium/components/search_engines.gypi
index 1e4500362f8..1ed485e4142 100644
--- a/chromium/components/search_engines.gypi
+++ b/chromium/components/search_engines.gypi
@@ -26,7 +26,7 @@
'pref_registry',
'rappor',
'search_engines/prepopulated_engines.gyp:prepopulated_engines',
- 'url_fixer',
+ 'url_formatter/url_formatter.gyp:url_formatter',
'webdata_common',
],
'export_dependent_settings': [
diff --git a/chromium/components/security_interstitials.gypi b/chromium/components/security_interstitials.gypi
new file mode 100644
index 00000000000..3092d03cd71
--- /dev/null
+++ b/chromium/components/security_interstitials.gypi
@@ -0,0 +1,28 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/security_interstitials/core
+ 'target_name': 'security_interstitials_core',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../net/net.gyp:net',
+ 'history_core_browser',
+ 'metrics',
+ 'rappor',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'security_interstitials/core/metrics_helper.cc',
+ 'security_interstitials/core/metrics_helper.h',
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/chromium/components/security_interstitials/DEPS b/chromium/components/security_interstitials/DEPS
new file mode 100644
index 00000000000..a32a580d0fe
--- /dev/null
+++ b/chromium/components/security_interstitials/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "+components/history/core/browser",
+ "+components/metrics",
+ "+components/rappor",
+ "+net/base"
+]
diff --git a/chromium/components/security_interstitials/OWNERS b/chromium/components/security_interstitials/OWNERS
new file mode 100644
index 00000000000..d46fc3fe61a
--- /dev/null
+++ b/chromium/components/security_interstitials/OWNERS
@@ -0,0 +1,6 @@
+estark@chromium.org
+felt@chromium.org
+mattm@chromium.org
+meacer@chromium.org
+nparker@chromium.org
+palmer@chromium.org \ No newline at end of file
diff --git a/chromium/components/security_interstitials/README b/chromium/components/security_interstitials/README
new file mode 100644
index 00000000000..82bfd142ed0
--- /dev/null
+++ b/chromium/components/security_interstitials/README
@@ -0,0 +1,4 @@
+Componentizing security interstitials is still in progress. Eventually this
+component will include most of the code from chrome/browser/interstitials/ as
+well as the various BlockingPage classes. It will be a layered component to
+allow for iOS support. \ No newline at end of file
diff --git a/chromium/components/security_interstitials/core/BUILD.gn b/chromium/components/security_interstitials/core/BUILD.gn
new file mode 100644
index 00000000000..d60bad3646c
--- /dev/null
+++ b/chromium/components/security_interstitials/core/BUILD.gn
@@ -0,0 +1,19 @@
+# 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.
+
+# GYP version: components/security_interstitials.gyp:security_interstitials_core
+static_library("core") {
+ sources = [
+ "metrics_helper.cc",
+ "metrics_helper.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/history/core/browser",
+ "//components/metrics",
+ "//components/rappor",
+ "//net",
+ ]
+}
diff --git a/chromium/components/security_interstitials/core/browser/resources/captive_portal.js b/chromium/components/security_interstitials/core/browser/resources/captive_portal.js
new file mode 100644
index 00000000000..2c7c460b896
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/captive_portal.js
@@ -0,0 +1,5 @@
+// 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.
+
+var CAPTIVEPORTAL_CMD_OPEN_LOGIN_PAGE = 'openLoginPage';
diff --git a/chromium/components/security_interstitials/core/browser/resources/extended_reporting.js b/chromium/components/security_interstitials/core/browser/resources/extended_reporting.js
new file mode 100644
index 00000000000..817b3ff6346
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/extended_reporting.js
@@ -0,0 +1,41 @@
+// 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.
+
+'use strict';
+
+// Other constants defined in security_interstitial_page.h.
+var SB_BOX_CHECKED = 'boxchecked';
+var SB_DISPLAY_CHECK_BOX = 'displaycheckbox';
+
+// This sets up the Extended Safe Browsing Reporting opt-in, either for
+// reporting malware or invalid certificate chains. Does nothing if the
+// interstitial type is not SAFEBROWSING or SSL or CAPTIVE_PORTAL.
+function setupExtendedReportingCheckbox() {
+ var interstitialType = loadTimeData.getString('type');
+ if (interstitialType != 'SAFEBROWSING' && interstitialType != 'SSL' &&
+ interstitialType != 'CAPTIVE_PORTAL') {
+ return;
+ }
+
+ if (!loadTimeData.getBoolean(SB_DISPLAY_CHECK_BOX)) {
+ return;
+ }
+
+ $('opt-in-label').innerHTML = loadTimeData.getString('optInLink');
+ $('opt-in-checkbox').checked = loadTimeData.getBoolean(SB_BOX_CHECKED);
+ $('extended-reporting-opt-in').classList.remove('hidden');
+
+ var className = interstitialType == 'SAFEBROWSING' ?
+ 'safe-browsing-opt-in' :
+ 'ssl-opt-in';
+ $('extended-reporting-opt-in').classList.add(className);
+
+ $('body').classList.add('extended-reporting-has-checkbox');
+
+ $('opt-in-checkbox').addEventListener('click', function() {
+ sendCommand($('opt-in-checkbox').checked ?
+ CMD_DO_REPORT :
+ CMD_DONT_REPORT);
+ });
+}
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/1x/brokenssl_red.png b/chromium/components/security_interstitials/core/browser/resources/images/1x/brokenssl_red.png
new file mode 100644
index 00000000000..cc4b1b39159
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/1x/brokenssl_red.png
Binary files differ
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/1x/captive_portal_page_icon.png b/chromium/components/security_interstitials/core/browser/resources/images/1x/captive_portal_page_icon.png
new file mode 100644
index 00000000000..11332a04312
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/1x/captive_portal_page_icon.png
Binary files differ
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/1x/clock.png b/chromium/components/security_interstitials/core/browser/resources/images/1x/clock.png
new file mode 100644
index 00000000000..1b1baf20f3d
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/1x/clock.png
Binary files differ
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/1x/stop_sign.png b/chromium/components/security_interstitials/core/browser/resources/images/1x/stop_sign.png
new file mode 100644
index 00000000000..f260d3310b3
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/1x/stop_sign.png
Binary files differ
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/2x/brokenssl_red.png b/chromium/components/security_interstitials/core/browser/resources/images/2x/brokenssl_red.png
new file mode 100644
index 00000000000..bc4fa0a8578
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/2x/brokenssl_red.png
Binary files differ
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/2x/captive_portal_page_icon.png b/chromium/components/security_interstitials/core/browser/resources/images/2x/captive_portal_page_icon.png
new file mode 100644
index 00000000000..b54ce21fecb
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/2x/captive_portal_page_icon.png
Binary files differ
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/2x/clock.png b/chromium/components/security_interstitials/core/browser/resources/images/2x/clock.png
new file mode 100644
index 00000000000..1f30a85dc2c
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/2x/clock.png
Binary files differ
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/2x/stop_sign.png b/chromium/components/security_interstitials/core/browser/resources/images/2x/stop_sign.png
new file mode 100644
index 00000000000..d91aa9cf6ee
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/2x/stop_sign.png
Binary files differ
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_ui.html b/chromium/components/security_interstitials/core/browser/resources/interstitial_ui.html
new file mode 100644
index 00000000000..4f425e52f39
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_ui.html
@@ -0,0 +1,55 @@
+<html>
+<head>
+ <title>Interstitials</title>
+</head>
+<body>
+ <h2>Choose an interstitial</h2>
+ <h3>SSL</h3>
+ <div>
+ <a href="ssl?overridable=1&strict_enforcement=0">example.com (generic, overridable)</a>
+ </div>
+ <div>
+ <a href="ssl?overridable=0&strict_enforcement=0">
+ example.com (generic, non-overridable)
+ </a>
+ </div>
+ <div>
+ <a href="ssl?overridable=0&strict_enforcement=1">
+ example.com (HSTS, non-overridable)
+ </a>
+ </div>
+ <div>
+ <a href="clock?clock_manipulation=2">Clock is ahead</a>
+ </div>
+ <div>
+ <a href="clock?clock_manipulation=-2">Clock is behind</a>
+ </div>
+ <h3>SafeBrowsing</h3>
+ <div>
+ <a href="safebrowsing?type=malware">Malware</a>
+ </div>
+ <div>
+ <a href="safebrowsing?type=phishing">Phishing</a>
+ </div>
+ <div>
+ <a href="safebrowsing?type=clientside_malware">Client Side Malware</a>
+ </div>
+ <div>
+ <a href="safebrowsing?type=clientside_phishing">Client Side Phishing</a>
+ </div>
+ <h3>Captive Portal</h3>
+ <div>
+ <a href="captiveportal">Captive Portal, Non-WiFi</a>
+ </div>
+ <div>
+ <a href="captiveportal?is_wifi=1">
+ Captive Portal, WiFi
+ </a>
+ </div>
+ <div>
+ <a href="captiveportal?is_wifi=1&wifi_name=CoffeeShopWiFi">
+ Captive Portal, WiFi with network name "CoffeeShopWiFi"
+ </a>
+ </div>
+</body>
+</html>
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.css b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.css
new file mode 100644
index 00000000000..0f1846565a4
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.css
@@ -0,0 +1,635 @@
+/* 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. */
+
+a {
+ color: #585858;
+}
+
+.bad-clock .icon {
+ background-image: -webkit-image-set(
+ url(images/1x/clock.png) 1x,
+ url(images/2x/clock.png) 2x);
+}
+
+body {
+ background-color: #f7f7f7;
+ color: #646464;
+}
+
+body.safe-browsing {
+ background-color: rgb(206, 52, 38);
+ color: white;
+}
+
+button {
+ -webkit-user-select: none;
+ background: rgb(76, 142, 250);
+ border: 0;
+ border-radius: 2px;
+ box-sizing: border-box;
+ color: #fff;
+ cursor: pointer;
+ float: right;
+ font-size: .875em;
+ margin: 0;
+ padding: 10px 24px;
+ transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+[dir='rtl'] button {
+ float: left;
+}
+
+button:active {
+ background: rgb(50, 102, 213);
+ outline: 0;
+}
+
+button:hover {
+ box-shadow: 0 1px 3px rgba(0, 0, 0, .50);
+}
+
+#debugging {
+ display: inline;
+ overflow: auto;
+}
+
+.debugging-content {
+ line-height: 1em;
+ margin-bottom: 0;
+ margin-top: 1em;
+}
+
+.debugging-title {
+ font-weight: bold;
+}
+
+#details {
+ color: #696969;
+ margin: 45px 0 50px;
+}
+
+#details p:not(:first-of-type) {
+ margin-top: 20px;
+}
+
+#details-button {
+ background: inherit;
+ border: 0;
+ float: none;
+ margin: 0;
+ padding: 10px 0;
+ text-decoration: underline;
+}
+
+#details-button:hover {
+ box-shadow: inherit;
+}
+
+.error-code {
+ color: #777;
+ display: inline;
+ font-size: .86667em;
+ margin-top: 15px;
+ opacity: .5;
+ text-transform: uppercase;
+}
+
+#error-debugging-info {
+ font-size: 0.8em;
+}
+
+h1 {
+ color: #333;
+ font-size: 1.6em;
+ font-weight: normal;
+ line-height: 1.25em;
+ margin-bottom: 16px;
+}
+
+h2 {
+ font-size: 1.2em;
+ font-weight: normal;
+}
+
+.hidden {
+ display: none;
+}
+
+html {
+ -webkit-text-size-adjust: 100%;
+ font-size: 125%;
+}
+
+.icon {
+ background-repeat: no-repeat;
+ background-size: 100%;
+ height: 72px;
+ margin: 0 0 40px;
+ width: 72px;
+}
+
+input[type=checkbox] {
+ opacity: 0;
+}
+
+input[type=checkbox]:focus ~ .checkbox {
+ outline: -webkit-focus-ring-color auto 5px;
+}
+
+.interstitial-wrapper {
+ box-sizing: border-box;
+ font-size: 1em;
+ line-height: 1.6em;
+ margin: 100px auto 0;
+ max-width: 600px;
+ width: 100%;
+}
+
+#main-message > p {
+ display: inline;
+}
+
+#extended-reporting-opt-in {
+ font-size: .875em;
+ margin-top: 39px;
+}
+
+#extended-reporting-opt-in label {
+ position: relative;
+}
+
+.nav-wrapper {
+ margin-top: 51px;
+}
+
+.nav-wrapper::after {
+ clear: both;
+ content: '';
+ display: table;
+ width: 100%;
+}
+
+.safe-browsing :-webkit-any(
+ a, #details, #details-button, h1, h2, p, .small-link) {
+ color: white;
+}
+
+.safe-browsing button {
+ background-color: rgba(255, 255, 255, .15);
+}
+
+.safe-browsing button:active {
+ background-color: rgba(255, 255, 255, .25);
+}
+
+.safe-browsing button:hover {
+ box-shadow: 0 2px 3px rgba(0, 0, 0, .5);
+}
+
+.safe-browsing .error-code {
+ display: none;
+}
+
+.safe-browsing .icon {
+ background-image: -webkit-image-set(
+ url(images/1x/stop_sign.png) 1x,
+ url(images/2x/stop_sign.png) 2x);
+}
+
+.small-link {
+ color: #696969;
+ font-size: .875em;
+}
+
+.ssl .icon {
+ background-image: -webkit-image-set(
+ url(images/1x/brokenssl_red.png) 1x,
+ url(images/2x/brokenssl_red.png) 2x);
+}
+
+.captive-portal .icon {
+ background-image: -webkit-image-set(
+ url(images/1x/captive_portal_page_icon.png) 1x,
+ url(images/2x/captive_portal_page_icon.png) 2x);
+}
+
+.checkbox {
+ background: transparent;
+ border: 1px solid white;
+ border-radius: 2px;
+ display: block;
+ height: 14px;
+ left: 0;
+ position: absolute;
+ right: 0;
+ top: -1px;
+ width: 14px;
+}
+
+.checkbox::before {
+ background: transparent;
+ border: 2px solid white;
+ border-right-width: 0;
+ border-top-width: 0;
+ content: '';
+ height: 4px;
+ left: 2px;
+ opacity: 0;
+ position: absolute;
+ top: 3px;
+ transform: rotate(-45deg);
+ width: 9px;
+}
+
+.ssl-opt-in .checkbox {
+ border-color: #696969;
+}
+
+.ssl-opt-in .checkbox::before {
+ border-color: #696969;
+}
+
+input[type=checkbox]:checked ~ .checkbox::before {
+ opacity: 1;
+}
+
+@media (max-width: 700px) {
+ .interstitial-wrapper {
+ padding: 0 10%;
+ }
+
+ #error-debugging-info {
+ overflow: auto;
+ }
+}
+
+@media (max-height: 600px) {
+ .error-code {
+ margin-top: 10px;
+ }
+}
+
+@media (max-width: 420px) {
+ button,
+ [dir='rtl'] button,
+ .small-link {
+ float: none;
+ font-size: .825em;
+ font-weight: 400;
+ margin: 0;
+ text-transform: uppercase;
+ width: 100%;
+ }
+
+ #details {
+ margin: 20px 0 20px 0;
+ }
+
+ #details p:not(:first-of-type) {
+ margin-top: 10px;
+ }
+
+ #details-button {
+ display: block;
+ margin-top: 20px;
+ text-align: center;
+ width: 100%;
+ }
+
+ .interstitial-wrapper {
+ padding: 0 5%;
+ }
+
+ #extended-reporting-opt-in {
+ margin-top: 24px;
+ }
+
+ .nav-wrapper {
+ margin-top: 30px;
+ }
+}
+
+/**
+ * Mobile specific styling.
+ * Navigation buttons are anchored to the bottom of the screen.
+ * Details message replaces the top content in its own scrollable area.
+ */
+
+@media (max-width: 420px) and (max-height: 736px) and (orientation: portrait) {
+ #details-button {
+ border: 0;
+ margin: 8px 0 0;
+ }
+
+ .secondary-button {
+ -webkit-margin-end: 0;
+ margin-top: 16px;
+ }
+}
+
+/* Fixed nav. */
+@media (min-width: 240px) and (max-width: 420px) and
+ (min-height: 401px) and (max-height: 736px) and (orientation:portrait),
+ (min-width: 421px) and (max-width: 736px) and (min-height: 240px) and
+ (max-height: 420px) and (orientation:landscape) {
+ body .nav-wrapper {
+ background: #f7f7f7;
+ bottom: 0;
+ box-shadow: 0 -22px 40px rgb(247, 247, 247);
+ left: 0;
+ margin: 0;
+ max-width: 736px;
+ padding-left: 24px;
+ padding-right: 24px;
+ position: fixed;
+ z-index: 1;
+ }
+
+ body.safe-browsing .nav-wrapper {
+ background: rgb(206, 52, 38);
+ box-shadow: 0 -22px 40px rgb(206, 52, 38);
+ }
+
+ .interstitial-wrapper {
+ max-width: 736px;
+ }
+
+ #details,
+ #main-content {
+ padding-bottom: 40px;
+ }
+}
+
+@media (max-width: 420px) and (max-height: 736px) and (orientation: portrait),
+ (max-width: 736px) and (max-height: 420px) and (orientation: landscape) {
+ body {
+ margin: 0 auto;
+ }
+
+ button,
+ [dir='rtl'] button,
+ button.small-link {
+ font-family: Roboto-Regular,Helvetica;
+ font-size: .933em;
+ font-weight: 600;
+ margin: 6px 0;
+ text-transform: uppercase;
+ }
+
+ .nav-wrapper {
+ box-sizing: border-box;
+ padding-bottom: 8px;
+ width: 100%;
+ }
+
+ .error-code {
+ margin-top: 0;
+ }
+
+ #details {
+ box-sizing: border-box;
+ height: auto;
+ margin: 0;
+ opacity: 1;
+ transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1);
+ }
+
+ #details.hidden,
+ #main-content.hidden {
+ display: block;
+ height: 0;
+ opacity: 0;
+ overflow: hidden;
+ transition: none;
+ }
+
+ #details-button {
+ padding-bottom: 16px;
+ padding-top: 16px;
+ }
+
+ h1 {
+ font-size: 1.5em;
+ margin-bottom: 8px;
+ }
+
+ .icon {
+ margin-bottom: 12px;
+ }
+
+ .interstitial-wrapper {
+ box-sizing: border-box;
+ margin: 24px auto 12px;
+ padding: 0 24px;
+ position: relative;
+ }
+
+ .interstitial-wrapper p {
+ font-size: .95em;
+ line-height: 1.61em;
+ margin-top: 8px;
+ }
+
+ #main-content {
+ margin: 0;
+ transition: opacity 100ms cubic-bezier(0.4, 0, 0.2, 1);
+ }
+
+ .small-link {
+ border: 0;
+ }
+
+ .suggested-left > #control-buttons,
+ .suggested-right > #control-buttons {
+ float: none;
+ margin: 0;
+ }
+}
+
+@media (min-height: 400px) and (orientation:portrait) {
+ .interstitial-wrapper {
+ margin-bottom: 145px;
+ }
+}
+
+@media (min-height: 299px) and (orientation:portrait) {
+ .nav-wrapper {
+ padding-bottom: 16px;
+ }
+}
+
+@media (min-height: 405px) and (max-height: 736px) and
+ (max-width: 420px) and (orientation:portrait) {
+ .icon {
+ margin-bottom: 24px;
+ }
+
+ .interstitial-wrapper {
+ margin-top: 64px;
+ }
+}
+
+@media (min-height: 480px) and (max-width: 420px) and
+ (max-height: 736px) and (orientation: portrait),
+ (min-height: 338px) and (max-height: 420px) and (max-width: 736px) and
+ (orientation: landscape) {
+ .icon {
+ margin-bottom: 24px;
+ }
+
+ .nav-wrapper {
+ padding-bottom: 24px;
+ }
+}
+
+@media (min-height: 500px) and (max-width: 414px) and (orientation: portrait) {
+ .interstitial-wrapper {
+ margin-top: 96px;
+ }
+}
+
+/* Phablet sizing */
+@media (min-width: 375px) and (min-height: 641px) and (max-height: 736px) and
+ (max-width: 414px) and (orientation: portrait) {
+ button,
+ [dir='rtl'] button,
+ .small-link {
+ font-size: 1em;
+ padding-bottom: 12px;
+ padding-top: 12px;
+ }
+
+ body:not(.offline) .icon {
+ height: 80px;
+ width: 80px;
+ }
+
+ #details-button {
+ margin-top: 28px;
+ }
+
+ h1 {
+ font-size: 1.7em;
+ }
+
+ .icon {
+ margin-bottom: 28px;
+ }
+
+ .interstitial-wrapper {
+ padding: 28px;
+ }
+
+ .interstitial-wrapper p {
+ font-size: 1.05em;
+ }
+
+ .nav-wrapper {
+ padding: 28px;
+ }
+}
+
+@media (min-width: 420px) and (max-width: 736px) and
+ (min-height: 240px) and (max-height: 298px) and
+ (orientation:landscape) {
+ body:not(.offline) .icon {
+ height: 50px;
+ width: 50px;
+ }
+
+ .icon {
+ padding-top: 0;
+ }
+
+ .interstitial-wrapper {
+ margin-top: 16px;
+ }
+
+ .nav-wrapper {
+ padding: 0 24px 8px;
+ }
+}
+
+@media (min-width: 420px) and (max-width: 736px) and
+ (min-height: 240px) and (max-height: 420px) and
+ (orientation:landscape) {
+ #details-button {
+ margin: 0;
+ }
+
+ .interstitial-wrapper {
+ margin-bottom: 70px;
+ }
+
+ .nav-wrapper {
+ margin-top: 0;
+ }
+
+ #extended-reporting-opt-in {
+ margin-top: 0;
+ }
+}
+
+/* Phablet landscape */
+@media (min-width: 680px) and (max-height: 414px) {
+ .interstitial-wrapper {
+ margin: 24px auto;
+ }
+
+ .nav-wrapper {
+ margin: 16px auto 0;
+ }
+}
+
+@media (max-height: 240px) and (orientation: landscape),
+ (max-height: 480px) and (orientation: portrait),
+ (max-width: 419px) and (max-height: 323px) {
+ body:not(.offline) .icon {
+ height: 56px;
+ width: 56px;
+ }
+
+ .icon {
+ margin-bottom: 16px;
+ }
+}
+
+/* Small mobile screens. No fixed nav. */
+@media (max-height: 400px) and (orientation: portrait),
+ (max-height: 239px) and (orientation: landscape),
+ (max-width: 419px) and (max-height: 399px) {
+ .interstitial-wrapper {
+ display: flex;
+ flex-direction: column;
+ margin-bottom: 0;
+ }
+
+ #details {
+ flex: 1 1 auto;
+ order: 0;
+ }
+
+ #main-content {
+ flex: 1 1 auto;
+ order: 0;
+ }
+
+ .nav-wrapper {
+ flex: 0 1 auto;
+ margin-top: 8px;
+ order: 1;
+ padding-left: 0;
+ padding-right: 0;
+ position: relative;
+ width: 100%;
+ }
+}
+
+@media (max-width: 239px) and (orientation: portrait) {
+ .nav-wrapper {
+ padding-left: 0;
+ padding-right: 0;
+ }
+}
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.html b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.html
new file mode 100644
index 00000000000..401060efc43
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<html i18n-values="dir:textdirection;lang:language">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport"
+ content="initial-scale=1, minimum-scale=1, width=device-width">
+ <title i18n-content="tabTitle"></title>
+ <link rel="stylesheet" href="interstitial_v2.css">
+ <script src="../../../../../ui/webui/resources/js/util.js"></script>
+ <script src="captive_portal.js"></script>
+ <script src="ssl.js"></script>
+ <script src="extended_reporting.js"></script>
+ <script src="interstitial_v2_mobile.js"></script>
+ <script src="interstitial_v2.js"></script>
+</head>
+<body id="body">
+ <div class="interstitial-wrapper">
+ <div id="main-content">
+ <div class="icon" id="icon"></div>
+ <div id="main-message">
+ <h1 i18n-content="heading"></h1>
+ <p i18n-values=".innerHTML:primaryParagraph"></p>
+ <div id="debugging">
+ <div id="error-code" class="error-code"></div>
+ <div id="error-debugging-info" class="hidden"></div>
+ </div>
+ </div>
+ <div id="extended-reporting-opt-in" class="hidden">
+ <label>
+ <input type="checkbox" id="opt-in-checkbox">
+ <span class="checkbox"></span>
+ <span id="opt-in-label"></span>
+ </label>
+ </div>
+ </div>
+ <div class="nav-wrapper">
+ <button i18n-content="primaryButtonText" id="primary-button"></button>
+ <button id="details-button" class="small-link"
+ i18n-content="openDetails"></button>
+ </div>
+ <div id="details" class="hidden">
+ <p i18n-values=".innerHTML:explanationParagraph"></p>
+ <p i18n-values=".innerHTML:finalParagraph" id="final-paragraph"></p>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.js b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.js
new file mode 100644
index 00000000000..c8a1ce52c41
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.js
@@ -0,0 +1,192 @@
+// 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.
+
+// This is the shared code for the new (Chrome 37) security interstitials. It is
+// used for both SSL interstitials and Safe Browsing interstitials.
+
+var expandedDetails = false;
+var keyPressState = 0;
+
+// Should match SecurityInterstitialCommands in security_interstitial_page.h
+var CMD_DONT_PROCEED = 0;
+var CMD_PROCEED = 1;
+// Ways for user to get more information
+var CMD_SHOW_MORE_SECTION = 2;
+var CMD_OPEN_HELP_CENTER = 3;
+var CMD_OPEN_DIAGNOSTIC = 4;
+// Primary button actions
+var CMD_RELOAD = 5;
+var CMD_OPEN_DATE_SETTINGS = 6;
+var CMD_OPEN_LOGIN = 7;
+// Safe Browsing Extended Reporting
+var CMD_DO_REPORT = 8;
+var CMD_DONT_REPORT = 9;
+var CMD_OPEN_REPORTING_PRIVACY = 10;
+// Report a phishing error.
+var CMD_REPORT_PHISHING_ERROR = 11;
+
+/**
+ * A convenience method for sending commands to the parent page.
+ * @param {string} cmd The command to send.
+ */
+function sendCommand(cmd) {
+ window.domAutomationController.setAutomationId(1);
+ window.domAutomationController.send(cmd);
+}
+
+/**
+ * This allows errors to be skippped by typing "danger" into the page.
+ * @param {string} e The key that was just pressed.
+ */
+function handleKeypress(e) {
+ var BYPASS_SEQUENCE = 'danger';
+ if (BYPASS_SEQUENCE.charCodeAt(keyPressState) == e.keyCode) {
+ keyPressState++;
+ if (keyPressState == BYPASS_SEQUENCE.length) {
+ sendCommand(CMD_PROCEED);
+ keyPressState = 0;
+ }
+ } else {
+ keyPressState = 0;
+ }
+}
+
+/**
+ * This appends a piece of debugging information to the end of the warning.
+ * When complete, the caller must also make the debugging div
+ * (error-debugging-info) visible.
+ * @param {string} title The name of this debugging field.
+ * @param {string} value The value of the debugging field.
+ */
+function appendDebuggingField(title, value) {
+ // The values input here are not trusted. Never use innerHTML on these
+ // values!
+ var spanTitle = document.createElement('span');
+ spanTitle.classList.add('debugging-title');
+ spanTitle.innerText = title + ': ';
+
+ var spanValue = document.createElement('span');
+ spanValue.classList.add('debugging-value');
+ spanValue.innerText = value;
+
+ var pElem = document.createElement('p');
+ pElem.classList.add('debugging-content');
+ pElem.appendChild(spanTitle);
+ pElem.appendChild(spanValue);
+ $('error-debugging-info').appendChild(pElem);
+}
+
+function toggleDebuggingInfo() {
+ $('error-debugging-info').classList.toggle('hidden');
+}
+
+function setupEvents() {
+ var overridable = loadTimeData.getBoolean('overridable');
+ var interstitialType = loadTimeData.getString('type');
+ var ssl = interstitialType == 'SSL';
+ var captivePortal = interstitialType == 'CAPTIVE_PORTAL';
+ var badClock = ssl && loadTimeData.getBoolean('bad_clock');
+ var hidePrimaryButton = badClock && loadTimeData.getBoolean(
+ 'hide_primary_button');
+
+ if (ssl) {
+ $('body').classList.add(badClock ? 'bad-clock' : 'ssl');
+ $('error-code').textContent = loadTimeData.getString('errorCode');
+ $('error-code').classList.remove('hidden');
+ } else if (captivePortal) {
+ $('body').classList.add('captive-portal');
+ } else {
+ $('body').classList.add('safe-browsing');
+ }
+
+ if (hidePrimaryButton) {
+ $('primary-button').classList.add('hidden');
+ } else {
+ $('primary-button').addEventListener('click', function() {
+ switch (interstitialType) {
+ case 'CAPTIVE_PORTAL':
+ sendCommand(CMD_OPEN_LOGIN);
+ break;
+
+ case 'SSL':
+ if (badClock)
+ sendCommand(CMD_OPEN_DATE_SETTINGS);
+ else if (overridable)
+ sendCommand(CMD_DONT_PROCEED);
+ else
+ sendCommand(CMD_RELOAD);
+ break;
+
+ case 'SAFEBROWSING':
+ sendCommand(CMD_DONT_PROCEED);
+ break;
+
+ default:
+ throw 'Invalid interstitial type';
+ }
+ });
+ }
+
+ if (overridable) {
+ // Captive portal page isn't overridable.
+ $('proceed-link').addEventListener('click', function(event) {
+ sendCommand(CMD_PROCEED);
+ });
+ } else if (!ssl) {
+ $('final-paragraph').classList.add('hidden');
+ }
+
+ if (ssl && overridable) {
+ $('proceed-link').classList.add('small-link');
+ } else if ($('help-link')) {
+ // Overridable SSL page doesn't have this link.
+ $('help-link').addEventListener('click', function(event) {
+ if (ssl || loadTimeData.getBoolean('phishing'))
+ sendCommand(CMD_OPEN_HELP_CENTER);
+ else
+ sendCommand(CMD_OPEN_DIAGNOSTIC);
+ });
+ }
+
+ if (captivePortal) {
+ // Captive portal page doesn't have details button.
+ $('details-button').classList.add('hidden');
+ } else {
+ $('details-button').addEventListener('click', function(event) {
+ var hiddenDetails = $('details').classList.toggle('hidden');
+
+ if (mobileNav) {
+ // Details appear over the main content on small screens.
+ $('main-content').classList.toggle('hidden', !hiddenDetails);
+ } else {
+ $('main-content').classList.remove('hidden');
+ }
+
+ $('details-button').innerText = hiddenDetails ?
+ loadTimeData.getString('openDetails') :
+ loadTimeData.getString('closeDetails');
+ if (!expandedDetails) {
+ // Record a histogram entry only the first time that details is opened.
+ sendCommand(CMD_SHOW_MORE_SECTION);
+ expandedDetails = true;
+ }
+ });
+ }
+
+ // TODO(felt): This should be simplified once the Finch trial is no longer
+ // needed.
+ if (interstitialType == 'SAFEBROWSING' &&
+ loadTimeData.getBoolean('phishing') && $('report-error-link')) {
+ $('report-error-link').addEventListener('click', function(event) {
+ sendCommand(CMD_REPORT_PHISHING_ERROR);
+ });
+ }
+
+ preventDefaultOnPoundLinkClicks();
+ setupExtendedReportingCheckbox();
+ setupSSLDebuggingInfo();
+ document.addEventListener('keypress', handleKeypress);
+}
+
+document.addEventListener('DOMContentLoaded', setupEvents);
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js
new file mode 100644
index 00000000000..f296232387c
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js
@@ -0,0 +1,50 @@
+// 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.
+
+var mobileNav = false;
+
+/**
+ * For small screen mobile the navigation buttons are moved
+ * below the advanced text.
+ */
+function onResize() {
+ var helpOuterBox = document.querySelector('#details');
+ var mainContent = document.querySelector('#main-content');
+ var mediaQuery = '(min-width: 240px) and (max-width: 420px) and ' +
+ '(max-height: 736px) and (min-height: 401px) and ' +
+ '(orientation: portrait), (max-width: 736px) and ' +
+ '(max-height: 420px) and (min-height: 240px) and ' +
+ '(min-width: 421px) and (orientation: landscape)';
+
+ var detailsHidden = helpOuterBox.classList.contains('hidden');
+ var runnerContainer = document.querySelector('.runner-container');
+
+ // Check for change in nav status.
+ if (mobileNav != window.matchMedia(mediaQuery).matches) {
+ mobileNav = !mobileNav;
+
+ // Handle showing the top content / details sections according to state.
+ if (mobileNav) {
+ mainContent.classList.toggle('hidden', !detailsHidden);
+ helpOuterBox.classList.toggle('hidden', detailsHidden);
+ if (runnerContainer) {
+ runnerContainer.classList.toggle('hidden', !detailsHidden);
+ }
+ } else if (!detailsHidden) {
+ // Non mobile nav with visible details.
+ mainContent.classList.remove('hidden');
+ helpOuterBox.classList.remove('hidden');
+ if (runnerContainer) {
+ runnerContainer.classList.remove('hidden');
+ }
+ }
+ }
+}
+
+function setupMobileNav() {
+ window.addEventListener('resize', onResize);
+ onResize();
+}
+
+document.addEventListener('DOMContentLoaded', setupMobileNav);
diff --git a/chromium/components/security_interstitials/core/browser/resources/ssl.js b/chromium/components/security_interstitials/core/browser/resources/ssl.js
new file mode 100644
index 00000000000..2c1a2b572bd
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/ssl.js
@@ -0,0 +1,18 @@
+// 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.
+
+function setupSSLDebuggingInfo() {
+ if (loadTimeData.getString('type') != 'SSL')
+ return;
+
+ // The titles are not internationalized because this is debugging information
+ // for bug reports, help center posts, etc.
+ appendDebuggingField('Subject', loadTimeData.getString('subject'));
+ appendDebuggingField('Issuer', loadTimeData.getString('issuer'));
+ appendDebuggingField('Expires on', loadTimeData.getString('expirationDate'));
+ appendDebuggingField('Current date', loadTimeData.getString('currentDate'));
+ appendDebuggingField('PEM encoded chain', loadTimeData.getString('pem'));
+
+ $('error-code').addEventListener('click', toggleDebuggingInfo);
+}
diff --git a/chromium/components/security_interstitials/core/metrics_helper.cc b/chromium/components/security_interstitials/core/metrics_helper.cc
new file mode 100644
index 00000000000..7466562841b
--- /dev/null
+++ b/chromium/components/security_interstitials/core/metrics_helper.cc
@@ -0,0 +1,152 @@
+// 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/security_interstitials/core/metrics_helper.h"
+
+#include "base/metrics/histogram.h"
+#include "components/history/core/browser/history_service.h"
+#include "components/rappor/rappor_service.h"
+#include "components/rappor/rappor_utils.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+
+namespace security_interstitials {
+
+namespace {
+
+// Used for setting bits in Rappor's "interstitial.*.flags"
+enum InterstitialFlagBits {
+ DID_PROCEED = 0,
+ IS_REPEAT_VISIT = 1,
+ HIGHEST_USED_BIT = 1
+};
+
+// Directly adds to the UMA histograms, using the same properties as
+// UMA_HISTOGRAM_ENUMERATION, because the macro doesn't allow non-constant
+// histogram names.
+void RecordSingleDecisionToMetrics(MetricsHelper::Decision decision,
+ const std::string& histogram_name) {
+ base::HistogramBase* histogram = base::LinearHistogram::FactoryGet(
+ histogram_name, 1, MetricsHelper::MAX_DECISION,
+ MetricsHelper::MAX_DECISION + 1,
+ base::HistogramBase::kUmaTargetedHistogramFlag);
+ histogram->Add(decision);
+}
+
+void RecordSingleInteractionToMetrics(MetricsHelper::Interaction interaction,
+ const std::string& histogram_name) {
+ base::HistogramBase* histogram = base::LinearHistogram::FactoryGet(
+ histogram_name, 1, MetricsHelper::MAX_INTERACTION,
+ MetricsHelper::MAX_INTERACTION + 1,
+ base::HistogramBase::kUmaTargetedHistogramFlag);
+ histogram->Add(interaction);
+}
+
+} // namespace
+
+MetricsHelper::ReportDetails::ReportDetails()
+ : rappor_report_type(rappor::NUM_RAPPOR_TYPES) {}
+
+MetricsHelper::MetricsHelper(const GURL& request_url,
+ const ReportDetails settings,
+ history::HistoryService* history_service,
+ rappor::RapporService* rappor_service)
+ : request_url_(request_url),
+ settings_(settings),
+ rappor_service_(rappor_service),
+ num_visits_(-1) {
+ DCHECK(!settings_.metric_prefix.empty());
+ if (settings_.rappor_report_type == rappor::NUM_RAPPOR_TYPES) // Default.
+ rappor_service_ = nullptr;
+ DCHECK(!rappor_service_ || !settings_.rappor_prefix.empty());
+ if (history_service) {
+ history_service->GetVisibleVisitCountToHost(
+ request_url_,
+ base::Bind(&MetricsHelper::OnGotHistoryCount, base::Unretained(this)),
+ &request_tracker_);
+ }
+}
+
+void MetricsHelper::RecordUserDecision(Decision decision) {
+ const std::string histogram_name(
+ "interstitial." + settings_.metric_prefix + ".decision");
+
+ RecordUserDecisionToMetrics(decision, histogram_name);
+ // Record additional information about sites that users have visited before.
+ // Report |decision| and SHOW together, filtered by the same history state
+ // so they they are paired regardless of when if num_visits_ is populated.
+ if (num_visits_ > 0 && (decision == PROCEED || decision == DONT_PROCEED)) {
+ RecordUserDecisionToMetrics(SHOW, histogram_name + ".repeat_visit");
+ RecordUserDecisionToMetrics(decision, histogram_name + ".repeat_visit");
+ }
+ RecordUserDecisionToRappor(decision);
+ RecordExtraUserDecisionMetrics(decision);
+}
+
+void MetricsHelper::RecordUserDecisionToMetrics(
+ Decision decision,
+ const std::string& histogram_name) {
+ // Record the decision, and additionally |with extra_suffix|.
+ RecordSingleDecisionToMetrics(decision, histogram_name);
+ if (!settings_.extra_suffix.empty()) {
+ RecordSingleDecisionToMetrics(
+ decision, histogram_name + "." + settings_.extra_suffix);
+ }
+}
+
+void MetricsHelper::RecordUserDecisionToRappor(Decision decision) {
+ if (!rappor_service_ || (decision != PROCEED && decision != DONT_PROCEED))
+ return;
+
+ scoped_ptr<rappor::Sample> sample =
+ rappor_service_->CreateSample(settings_.rappor_report_type);
+
+ // This will populate, for example, "intersitial.malware.domain" or
+ // "interstitial.ssl2.domain". |domain| will be empty for hosts w/o TLDs.
+ const std::string domain =
+ rappor::GetDomainAndRegistrySampleFromGURL(request_url_);
+ sample->SetStringField("domain", domain);
+
+ // Only report history and decision if we have history data.
+ if (num_visits_ >= 0) {
+ int flags = 0;
+ if (decision == PROCEED)
+ flags |= 1 << InterstitialFlagBits::DID_PROCEED;
+ if (num_visits_ > 0)
+ flags |= 1 << InterstitialFlagBits::IS_REPEAT_VISIT;
+ // e.g. "interstitial.malware.flags"
+ sample->SetFlagsField("flags", flags,
+ InterstitialFlagBits::HIGHEST_USED_BIT + 1);
+ }
+ rappor_service_->RecordSampleObj("interstitial." + settings_.rappor_prefix,
+ sample.Pass());
+}
+
+void MetricsHelper::RecordUserInteraction(Interaction interaction) {
+ const std::string histogram_name(
+ "interstitial." + settings_.metric_prefix + ".interaction");
+
+ RecordSingleInteractionToMetrics(interaction, histogram_name);
+ if (!settings_.extra_suffix.empty()) {
+ RecordSingleInteractionToMetrics(
+ interaction, histogram_name + "." + settings_.extra_suffix);
+ }
+ RecordExtraUserInteractionMetrics(interaction);
+}
+
+void MetricsHelper::RecordShutdownMetrics() {
+ RecordExtraShutdownMetrics();
+}
+
+int MetricsHelper::NumVisits() {
+ return num_visits_;
+}
+
+void MetricsHelper::OnGotHistoryCount(bool success,
+ int num_visits,
+ base::Time /*first_visit*/) {
+ if (success)
+ num_visits_ = num_visits;
+}
+
+} // namespace security_interstitials
diff --git a/chromium/components/security_interstitials/core/metrics_helper.h b/chromium/components/security_interstitials/core/metrics_helper.h
new file mode 100644
index 00000000000..e6102017edd
--- /dev/null
+++ b/chromium/components/security_interstitials/core/metrics_helper.h
@@ -0,0 +1,125 @@
+// 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_SECURITY_INTERSTITIALS_CORE_METRICS_HELPER_H_
+#define COMPONENTS_SECURITY_INTERSTITIALS_CORE_METRICS_HELPER_H_
+
+#include <string>
+
+#include "base/task/cancelable_task_tracker.h"
+#include "base/time/time.h"
+#include "components/rappor/rappor_service.h"
+#include "url/gurl.h"
+
+namespace history {
+class HistoryService;
+}
+
+namespace security_interstitials {
+
+// MetricsHelper records user warning interactions in a common way via METRICS
+// histograms and, optionally, RAPPOR metrics. The class will generate the
+// following histograms:
+// METRICS: interstitial.<metric_prefix>.decision[.repeat_visit]
+// METRICS: interstitial.<metric_prefix>.interaction[.repeat_visi]
+// RAPPOR: interstitial.<rappor_prefix>
+// wherein |metric_prefix| and |rappor_prefix| are specified via ReportDetails.
+// repeat_visit is also generated if the user has seen the page before.
+//
+// If |extra_suffix| is not empty, MetricsHelper will append ".<extra_suffix>"
+// to generate an additional 2 or 4 more metrics.
+class MetricsHelper {
+ public:
+ // These enums are used for histograms. Don't reorder, delete, or insert
+ // elements. New elements should be added at the end (right before the max).
+ enum Decision {
+ SHOW,
+ PROCEED,
+ DONT_PROCEED,
+ PROCEEDING_DISABLED,
+ MAX_DECISION
+ };
+ enum Interaction {
+ TOTAL_VISITS,
+ SHOW_ADVANCED,
+ SHOW_PRIVACY_POLICY,
+ SHOW_DIAGNOSTIC,
+ SHOW_LEARN_MORE,
+ RELOAD,
+ OPEN_TIME_SETTINGS,
+ SET_EXTENDED_REPORTING_ENABLED,
+ SET_EXTENDED_REPORTING_DISABLED,
+ EXTENDED_REPORTING_IS_ENABLED,
+ REPORT_PHISHING_ERROR,
+ MAX_INTERACTION
+ };
+
+ // metric_prefix: Histogram prefix for UMA.
+ // examples: "phishing", "ssl_overridable"
+ // extra_suffix: If not-empty, will generate second set of metrics by
+ // placing at the end of the metric name. Examples:
+ // "from_datasaver", "from_device"
+ // rappor_prefix: Metric prefix for Rappor.
+ // examples: "phishing", "ssl2"
+ // rappor_report_type: Used to differentiate UMA and Safe Browsing statistics.
+ // The rappor preferences can be left blank if rappor_service is not set.
+ struct ReportDetails {
+ ReportDetails();
+ std::string metric_prefix;
+ std::string extra_suffix;
+ std::string rappor_prefix;
+ rappor::RapporType rappor_report_type;
+ };
+
+ // Args:
+ // url: URL of page that triggered the interstitial. Only origin is used.
+ // history_service: Set this to record metrics based on whether the user
+ // has visited this hostname before.
+ // rappor_service: If you want RAPPOR statistics, provide a service,
+ // settings.rappor_prefix, and settings.rappor_report_type.
+ // settings: Specify reporting details (prefixes and report types).
+ // sampling_event_name: Event name for Experience Sampling.
+ // e.g. "phishing_interstitial_"
+ MetricsHelper(const GURL& url,
+ const ReportDetails settings,
+ history::HistoryService* history_service,
+ rappor::RapporService* rappor_service);
+ virtual ~MetricsHelper() {}
+
+ // Records a user decision or interaction to the appropriate UMA metrics
+ // histogram and potentially in a RAPPOR metric.
+ void RecordUserDecision(Decision decision);
+ void RecordUserInteraction(Interaction interaction);
+ void RecordShutdownMetrics();
+
+ // Number of times user visited this origin before. -1 means not-yet-set.
+ int NumVisits();
+
+ protected:
+ // Subclasses should implement any embedder-specific recording logic in these
+ // methods. They'll be invoked from the matching Record methods.
+ virtual void RecordExtraUserDecisionMetrics(Decision decision) = 0;
+ virtual void RecordExtraUserInteractionMetrics(Interaction interaction) = 0;
+ virtual void RecordExtraShutdownMetrics() = 0;
+
+ private:
+ // Used to query the HistoryService to see if the URL is in history. It will
+ // only be invoked if the constructor received |history_service|.
+ void OnGotHistoryCount(bool success, int num_visits, base::Time first_visit);
+
+ void RecordUserDecisionToMetrics(Decision decision,
+ const std::string& histogram_name);
+ void RecordUserDecisionToRappor(Decision decision);
+ const GURL request_url_;
+ const ReportDetails settings_;
+ rappor::RapporService* rappor_service_;
+ int num_visits_;
+ base::CancelableTaskTracker request_tracker_;
+
+ DISALLOW_COPY_AND_ASSIGN(MetricsHelper);
+};
+
+} // namespace security_interstitials
+
+#endif // COMPONENTS_SECURITY_INTERSTITIALS_CORE_METRICS_HELPER_H_
diff --git a/chromium/components/security_interstitials_strings.grdp b/chromium/components/security_interstitials_strings.grdp
new file mode 100644
index 00000000000..a5a7f139203
--- /dev/null
+++ b/chromium/components/security_interstitials_strings.grdp
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <!-- Shared strings for SSL-related interstitials -->
+ <message name="IDS_SSL_OPEN_DETAILS_BUTTON" desc="The text for the button that expands the details on an error page. Paired with IDS_SSL_CLOSE_DETAILS_BUTTON.">
+ Advanced
+ </message>
+ <message name="IDS_SSL_CLOSE_DETAILS_BUTTON" desc="The text for the button that hides the details on an error page. Paired with IDS_SSL_CLOSE_DETAILS_BUTTON.">
+ Hide advanced
+ </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
+ </message>
+ <message name="IDS_CLOCK_ERROR_AHEAD_HEADING" desc="Large heading. Context: the error page that's shown when the device clock is too far in the past.">
+ Your clock is ahead
+ </message>
+ <message name="IDS_CLOCK_ERROR_BEHIND_HEADING" desc="Large heading. Context: the error page that's shown when the device clock is too far in the past.">
+ Your clock is behind
+ </message>
+ <message name="IDS_CLOCK_ERROR_UPDATE_DATE_AND_TIME" desc="Button text. Context: error shown when the device clock is wrong. The button takes the user to the operating system date and time settings.">
+ Update date and time
+ </message>
+ <if expr="not is_android and not is_ios">
+ <message name="IDS_CLOCK_ERROR_PRIMARY_PARAGRAPH" desc="Main paragraph of an error message. Context: error shown when the browser can't load a page because the computer's clock is wrong.">
+ A private connection to <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="DOMAIN">$1<ex>paypal.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> can't be established because your computer's date and time (<ph name="DATE_AND_TIME">$2<ex>Monday, January 1, 1970 2:44:30 PM</ex></ph>) are incorrect.
+ </message>
+ </if>
+ <if expr="is_android">
+ <message name="IDS_CLOCK_ERROR_PRIMARY_PARAGRAPH" desc="Main paragraph of an error message. Context: error shown when the browser can't load a page because the Android device's clock is wrong.">
+ A private connection to <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="DOMAIN">$1<ex>paypal.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> can't be established because your device's date and time (<ph name="DATE_AND_TIME">$2<ex>Monday, January 1, 1970 2:44:30 PM</ex></ph>) are incorrect.
+ </message>
+ </if>
+ <if expr="is_ios">
+ <message name="IDS_CLOCK_ERROR_PRIMARY_PARAGRAPH" desc="Main paragraph of an error message. Context: error shown when the browser can't load a page because the device's clock is wrong. This paragraph explains the situation and gives instructions to fix it on iOS.">
+ &lt;p&gt;A private connection to <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="DOMAIN">$1<ex>paypal.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> can't be established because your device's date and time (<ph name="DATE_AND_TIME">$2<ex>Monday, January 1, 1970 2:44:30 PM</ex></ph>) are incorrect.&lt;/p&gt;
+
+ &lt;p&gt;Please adjust the date and time from the &lt;strong&gt;General&lt;/strong&gt; section of the &lt;strong&gt;Settings&lt;/strong&gt; app.&lt;/p&gt;
+ </message>
+ </if>
+ <if expr="_google_chrome">
+ <message name="IDS_CLOCK_ERROR_EXPLANATION" desc="Body text under an 'Advanced' button. Context: error shown when the browser can't load a page because the device's clock is wrong. This paragraph explains why a correct clock is necessary.">
+ To establish a secure connection, your clock needs to be set correctly. This is because the certificates that websites use to identify themselves are only valid for specific periods of time. Since your device's clock is incorrect, Google Chrome cannot verify these certificates.
+ </message>
+ </if>
+ <if expr="not _google_chrome">
+ <message name="IDS_CLOCK_ERROR_EXPLANATION" desc="Body text under an 'Advanced' button. Context: error shown when the browser can't load a page because the device's clock is wrong. This paragraph explains why a correct clock is necessary.">
+ To establish a secure connection, your clock needs to be set correctly. This is because the certificates that websites use to identify themselves are only valid for specific periods of time. Since your device's clock is incorrect, Chromium cannot verify these certificates.
+ </message>
+ </if>
+
+</grit-part> \ No newline at end of file
diff --git a/chromium/components/sessions.gypi b/chromium/components/sessions.gypi
index b6e6616c657..8dc4826b131 100644
--- a/chromium/components/sessions.gypi
+++ b/chromium/components/sessions.gypi
@@ -8,24 +8,38 @@
# be a separate shared library since one symbol is implemented higher up in
# the sessions_content/ios layer.
'sessions_core_sources': [
- 'sessions/base_session_service.cc',
- 'sessions/base_session_service.h',
- 'sessions/base_session_service_commands.cc',
- 'sessions/base_session_service_commands.h',
- 'sessions/base_session_service_delegate.h',
+ 'sessions/core/base_session_service.cc',
+ 'sessions/core/base_session_service.h',
+ 'sessions/core/base_session_service_commands.cc',
+ 'sessions/core/base_session_service_commands.h',
+ 'sessions/core/base_session_service_delegate.h',
+ 'sessions/core/live_tab.cc',
+ 'sessions/core/live_tab.h',
+ 'sessions/core/live_tab_context.h',
+ 'sessions/core/persistent_tab_restore_service.cc',
+ 'sessions/core/persistent_tab_restore_service.h',
'sessions/core/serialized_navigation_driver.h',
- 'sessions/serialized_navigation_entry.cc',
- 'sessions/serialized_navigation_entry.h',
- 'sessions/session_backend.cc',
- 'sessions/session_backend.h',
- 'sessions/session_command.cc',
- 'sessions/session_command.h',
- 'sessions/session_id.cc',
- 'sessions/session_id.h',
- 'sessions/session_service_commands.cc',
- 'sessions/session_service_commands.h',
- 'sessions/session_types.cc',
- 'sessions/session_types.h',
+ 'sessions/core/serialized_navigation_entry.cc',
+ 'sessions/core/serialized_navigation_entry.h',
+ 'sessions/core/session_backend.cc',
+ 'sessions/core/session_backend.h',
+ 'sessions/core/session_command.cc',
+ 'sessions/core/session_command.h',
+ 'sessions/core/session_constants.cc',
+ 'sessions/core/session_constants.h',
+ 'sessions/core/session_id.cc',
+ 'sessions/core/session_id.h',
+ 'sessions/core/session_service_commands.cc',
+ 'sessions/core/session_service_commands.h',
+ 'sessions/core/session_types.cc',
+ 'sessions/core/session_types.h',
+ 'sessions/core/tab_restore_service.cc',
+ 'sessions/core/tab_restore_service.h',
+ 'sessions/core/tab_restore_service_client.cc',
+ 'sessions/core/tab_restore_service_client.h',
+ 'sessions/core/tab_restore_service_helper.cc',
+ 'sessions/core/tab_restore_service_helper.h',
+ 'sessions/core/tab_restore_service_observer.h',
],
},
'targets': [
@@ -43,14 +57,14 @@
],
'sources': [
# Note: sources list duplicated in GN build.
- 'sessions/serialized_navigation_entry_test_helper.cc',
- 'sessions/serialized_navigation_entry_test_helper.h',
+ 'sessions/core/serialized_navigation_entry_test_helper.cc',
+ 'sessions/core/serialized_navigation_entry_test_helper.h',
],
'conditions': [
['OS!="ios" and OS!="android"', {
'sources': [
- 'sessions/base_session_service_test_helper.cc',
- 'sessions/base_session_service_test_helper.h',
+ 'sessions/core/base_session_service_test_helper.cc',
+ 'sessions/core/base_session_service_test_helper.h',
],
}],
],
@@ -75,6 +89,7 @@
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../url/url.gyp:url_lib',
+ 'keyed_service_core',
],
'include_dirs': [
'..',
@@ -86,13 +101,28 @@
# Note: sources list duplicated in GN build.
'<@(sessions_core_sources)',
+ 'sessions/content/content_live_tab.cc',
+ 'sessions/content/content_live_tab.h',
+ 'sessions/content/content_platform_specific_tab_data.cc',
+ 'sessions/content/content_platform_specific_tab_data.h',
'sessions/content/content_serialized_navigation_builder.cc',
'sessions/content/content_serialized_navigation_builder.h',
'sessions/content/content_serialized_navigation_driver.cc',
'sessions/content/content_serialized_navigation_driver.h',
],
- },
- ],
+ 'conditions': [
+ ['OS=="android"', {
+ 'sources': [
+ 'sessions/core/in_memory_tab_restore_service.cc',
+ 'sessions/core/in_memory_tab_restore_service.h',
+ ],
+ 'sources!': [
+ 'sessions/core/persistent_tab_restore_service.cc',
+ ],
+ },
+ ],
+ ],
+ }],
}, { # OS==ios
'targets': [
{
@@ -106,6 +136,7 @@
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../url/url.gyp:url_lib',
+ 'keyed_service_core',
],
'include_dirs': [
'..',
@@ -116,6 +147,8 @@
'sources': [
'<@(sessions_core_sources)',
+ 'sessions/ios/ios_live_tab.cc',
+ 'sessions/ios/ios_live_tab.h',
'sessions/ios/ios_serialized_navigation_builder.cc',
'sessions/ios/ios_serialized_navigation_builder.h',
'sessions/ios/ios_serialized_navigation_driver.cc',
diff --git a/chromium/components/signin.gypi b/chromium/components/signin.gypi
index 15cb1d8ddad..800859efb0a 100644
--- a/chromium/components/signin.gypi
+++ b/chromium/components/signin.gypi
@@ -32,10 +32,13 @@
'../google_apis/google_apis.gyp:google_apis',
'../net/net.gyp:net',
'../sql/sql.gyp:sql',
+ '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_proto_cpp',
'../third_party/icu/icu.gyp:icui18n',
'../third_party/icu/icu.gyp:icuuc',
'content_settings_core_browser',
'content_settings_core_common',
+ 'google_core_browser',
+ 'invalidation_public',
'keyed_service_core',
'os_crypt',
'signin_core_common',
@@ -50,23 +53,40 @@
'signin/core/browser/about_signin_internals.h',
'signin/core/browser/account_fetcher_service.cc',
'signin/core/browser/account_fetcher_service.h',
+ 'signin/core/browser/account_info.cc',
+ 'signin/core/browser/account_info.h',
+ 'signin/core/browser/account_info_fetcher.cc',
+ 'signin/core/browser/account_info_fetcher.h',
'signin/core/browser/account_reconcilor.cc',
'signin/core/browser/account_reconcilor.h',
'signin/core/browser/account_tracker_service.cc',
'signin/core/browser/account_tracker_service.h',
+ 'signin/core/browser/android/component_jni_registrar.cc',
+ 'signin/core/browser/android/component_jni_registrar.h',
+ 'signin/core/browser/child_account_info_fetcher.cc',
+ 'signin/core/browser/child_account_info_fetcher.h',
+ 'signin/core/browser/child_account_info_fetcher_android.cc',
+ 'signin/core/browser/child_account_info_fetcher_android.h',
+ 'signin/core/browser/child_account_info_fetcher_impl.cc',
+ 'signin/core/browser/child_account_info_fetcher_impl.h',
'signin/core/browser/device_activity_fetcher.cc',
'signin/core/browser/device_activity_fetcher.h',
'signin/core/browser/gaia_cookie_manager_service.cc',
'signin/core/browser/gaia_cookie_manager_service.h',
+ 'signin/core/browser/profile_identity_provider.cc',
+ 'signin/core/browser/profile_identity_provider.h',
'signin/core/browser/profile_oauth2_token_service.cc',
'signin/core/browser/profile_oauth2_token_service.h',
'signin/core/browser/refresh_token_annotation_request.cc',
'signin/core/browser/refresh_token_annotation_request.h',
+ 'signin/core/browser/signin_client.cc',
'signin/core/browser/signin_client.h',
'signin/core/browser/signin_cookie_changed_subscription.cc',
'signin/core/browser/signin_cookie_changed_subscription.h',
'signin/core/browser/signin_error_controller.cc',
'signin/core/browser/signin_error_controller.h',
+ 'signin/core/browser/signin_header_helper.cc',
+ 'signin/core/browser/signin_header_helper.h',
'signin/core/browser/signin_internals_util.cc',
'signin/core/browser/signin_internals_util.h',
'signin/core/browser/signin_manager.cc',
@@ -85,6 +105,15 @@
'signin/core/browser/webdata/token_web_data.h',
],
'conditions': [
+ ['OS=="android"', {
+ 'dependencies': [
+ 'signin_core_browser_jni_headers',
+ ],
+ 'sources!': [
+ 'signin/core/browser/child_account_info_fetcher_impl.cc',
+ 'signin/core/browser/child_account_info_fetcher_impl.h',
+ ],
+ }],
['chromeos==1', {
'sources!': [
'signin/core/browser/signin_manager.cc',
@@ -107,35 +136,93 @@
],
'sources': [
# Note: file list duplicated in GN build.
+ 'signin/core/browser/fake_account_fetcher_service.cc',
+ 'signin/core/browser/fake_account_fetcher_service.h',
'signin/core/browser/fake_auth_status_provider.cc',
'signin/core/browser/fake_auth_status_provider.h',
+ 'signin/core/browser/fake_profile_oauth2_token_service.cc',
+ 'signin/core/browser/fake_profile_oauth2_token_service.h',
+ 'signin/core/browser/fake_signin_manager.cc',
+ 'signin/core/browser/fake_signin_manager.h',
'signin/core/browser/test_signin_client.cc',
'signin/core/browser/test_signin_client.h',
],
},
],
'conditions': [
+ ['OS == "android"', {
+ 'targets': [
+ {
+ # GN version: //components/signin/core/browser/android:java
+ 'target_name': 'signin_core_browser_java',
+ 'type': 'none',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../sync/sync.gyp:sync_java',
+ ],
+ 'variables': {
+ 'java_in_dir': 'signin/core/browser/android/java',
+ },
+ 'includes': [ '../build/java.gypi' ],
+ },
+ {
+ # GN version: //components/signin/core/browser/android:jni_headers
+ 'target_name': 'signin_core_browser_jni_headers',
+ 'type': 'none',
+ 'sources': [
+ 'signin/core/browser/android/java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java',
+ ],
+ 'variables': {
+ 'jni_gen_package': 'components/signin',
+ },
+ 'includes': [ '../build/jni_generator.gypi' ],
+ },
+ ],
+ }],
['OS == "ios"', {
+ # GN version: //components/signin/core/browser:ios
'targets': [
{
- # GN version: //components/signin/core/browser:ios
'target_name': 'signin_ios_browser',
'type': 'static_library',
'dependencies': [
+ '../ios/web/ios_web.gyp:ios_web',
'signin_core_browser',
- '../ios/provider/ios_components.gyp:ios_components',
],
'include_dirs': [
'..',
],
'sources': [
# Note: file list duplicated in GN build.
+ 'signin/ios/browser/account_consistency_service.h',
+ 'signin/ios/browser/account_consistency_service.mm',
+ 'signin/ios/browser/manage_accounts_delegate.h',
'signin/ios/browser/merge_session_observer_bridge.h',
'signin/ios/browser/merge_session_observer_bridge.mm',
'signin/ios/browser/oauth2_token_service_observer_bridge.h',
'signin/ios/browser/oauth2_token_service_observer_bridge.mm',
'signin/ios/browser/profile_oauth2_token_service_ios_delegate.h',
'signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm',
+ 'signin/ios/browser/profile_oauth2_token_service_ios_provider.h',
+ ],
+ },
+ {
+ 'target_name': 'signin_ios_browser_test_support',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../google_apis/google_apis.gyp:google_apis_test_support',
+ 'signin_ios_browser',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: file list duplicated in GN build.
+ 'signin/ios/browser/fake_profile_oauth2_token_service_ios_delegate.h',
+ 'signin/ios/browser/fake_profile_oauth2_token_service_ios_delegate.mm',
+ 'signin/ios/browser/fake_profile_oauth2_token_service_ios_provider.h',
+ 'signin/ios/browser/fake_profile_oauth2_token_service_ios_provider.mm',
],
},
],
diff --git a/chromium/components/ssl_errors.gypi b/chromium/components/ssl_errors.gypi
new file mode 100644
index 00000000000..b66444b08f3
--- /dev/null
+++ b/chromium/components/ssl_errors.gypi
@@ -0,0 +1,27 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/ssl_errors
+ 'target_name': 'ssl_errors',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base_i18n',
+ '../net/net.gyp:net',
+ '../ui/base/ui_base.gyp:ui_base',
+ 'components_strings.gyp:components_strings',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'ssl_errors/error_info.cc',
+ 'ssl_errors/error_info.h',
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/chromium/components/ssl_errors_strings.grdp b/chromium/components/ssl_errors_strings.grdp
new file mode 100644
index 00000000000..6d8ba6b1b07
--- /dev/null
+++ b/chromium/components/ssl_errors_strings.grdp
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+
+ <message name="IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS" desc="Details for an unsafe common name in an X509 certificate">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is from <ph name="DOMAIN2">&lt;strong&gt;$2<ex>fakepaypal.com</ex>&lt;/strong&gt;</ph>. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ <message name="IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION" desc="Description for an unsafe common name in an X509 certificate">
+ Server's certificate does not match the URL.
+ </message>
+
+ <message name="IDS_CERT_ERROR_EXPIRED_DETAILS" desc="Details for an expired X509 certificate [ICU Syntax]">
+ {1, plural,
+ =1 {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate expired yesterday. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE">{2, date, full}<ex>Monday, July 16, 2012</ex></ph>. Does that look right? If not, you should correct your system's clock and then refresh this page.}
+ other {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate expired # days ago. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE">{2, date, full}<ex>Monday, July 16, 2012</ex></ph>. Does that look right? If not, you should correct your system's clock and then refresh this page.}}
+ </message>
+ <message name="IDS_CERT_ERROR_EXPIRED_DESCRIPTION" desc="Description for an expired X509 certificate">
+ Server's certificate has expired.
+ </message>
+
+ <message name="IDS_CERT_ERROR_NOT_YET_VALID_DETAILS" desc="Details for an X509 certificate that is not yet valid [ICU Syntax]">
+ {1, plural,
+ =1 {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is supposedly from tomorrow. This may be caused by a misconfiguration or an attacker intercepting your connection.}
+ other {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is supposedly from # days in the future. This may be caused by a misconfiguration or an attacker intercepting your connection.}}
+ </message>
+ <message name="IDS_CERT_ERROR_NOT_YET_VALID_DESCRIPTION" desc="Description for an X509 certificate that is not yet valid">
+ Server's certificate is not yet valid.
+ </message>
+
+ <message name="IDS_CERT_ERROR_NOT_VALID_AT_THIS_TIME_DETAILS" desc="Details for a chain with a X509 certificate that is not valid at this time.">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not valid at this time. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ <message name="IDS_CERT_ERROR_NOT_VALID_AT_THIS_TIME_DESCRIPTION" desc="Description for a chain with a X509 certificate that is not valid at this time.">
+ Server's certificate is not valid at this time.
+ </message>
+
+ <message name="IDS_CERT_ERROR_CHAIN_EXPIRED_DETAILS" desc="Details for an expired root or intermediate cert in chain">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate expired. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_TIME">$3<ex>July 18, 2012</ex></ph>. Does that look right? If not, you should correct your system's clock and then refresh this page.
+ </message>
+ <message name="IDS_CERT_ERROR_CHAIN_EXPIRED_DESCRIPTION" desc="Description for an expired intermediate/root certificate in chain">
+ A root or intermediate certificate has expired.
+ </message>
+
+ <message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DESCRIPTION" desc="Description for an X509 certificate with an invalid authority">
+ Server's certificate is not trusted.
+ </message>
+
+ <message name="IDS_CERT_ERROR_CONTAINS_ERRORS_DETAILS" desc="Details of the error page for an X509 certificate that contains errors">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate contains errors. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ <message name="IDS_CERT_ERROR_CONTAINS_ERRORS_DESCRIPTION" desc="Description of the error page for an X509 certificate that contains errors">
+ Server's certificate contains errors.
+ </message>
+
+ <message name="IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DETAILS" desc="Details for being unable to check revocation status of an X509 certificate">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate might be revoked. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ <message name="IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DESCRIPTION" desc="Description for being unable to check revocation status of an X509 certificate">
+ Server's certificate cannot be checked.
+ </message>
+
+ <message name="IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DETAILS" desc="Details for not finding a revocation mechanism in an X509 certificate">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate might be revoked. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ <message name="IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DESCRIPTION" desc="Description for not finding a revocation mechanism in an X509 certificate">
+ No revocation mechanism found.
+ </message>
+
+ <message name="IDS_CERT_ERROR_REVOKED_CERT_DETAILS" desc="Details of the error page for a revoked certificate">
+ You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the certificate that the server presented has been revoked by its issuer. This means that the security credentials the server presented absolutely should not be trusted. You may be communicating with an attacker.
+ </message>
+ <message name="IDS_CERT_ERROR_REVOKED_CERT_DESCRIPTION" desc="Description of the error page for a revoked certificate">
+ Server's certificate has been revoked.
+ </message>
+
+ <message name="IDS_CERT_ERROR_INVALID_CERT_DETAILS" desc="Details of the error page for an X509 certificate that is invalid">
+ You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented an invalid certificate.
+ </message>
+ <message name="IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION" desc="Description of the error page for an X509 certificate that is invalid">
+ Server's certificate is invalid.
+ </message>
+
+ <message name="IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DETAILS" desc="Details of the error page for a certificate signed using a weak signature algorithm">
+ You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented a certificate signed using a weak signature algorithm. This means that the security credentials the server presented could have been forged, and the server may not be the server you expected (you may be communicating with an attacker).
+ </message>
+ <message name="IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DESCRIPTION" desc="Description of the error page for a certificate signed using a weak signature algorithm">
+ Server's certificate is signed using a weak signature algorithm.
+ </message>
+
+ <message name="IDS_CERT_ERROR_WEAK_KEY_DETAILS" desc="Details of the error page for a certificate containing a weak key">
+ You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented a certificate containing a weak key. An attacker could have broken the private key, and the server may not be the server you expected (you may be communicating with an attacker).
+ </message>
+ <message name="IDS_CERT_ERROR_WEAK_KEY_DESCRIPTION" desc="Description of the error page for a certificate containing a weak key">
+ The server certificate contains a weak cryptographic key.
+ </message>
+
+ <message name="IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_DETAILS" desc="Details of the error page for a certificate that contains a name outside of its scope">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate might have been issued fraudulently. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ <message name="IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_DESCRIPTION" desc="Description of the error page for a certificate that contains a name outside of its scope">
+ Server's certificate violates name constraints.
+ </message>
+ <message name="IDS_CERT_ERROR_VALIDITY_TOO_LONG_DETAILS" desc="Details of the error page for a certificate whose validity period is too long">
+ You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented a certificate whose validity period is too long to be trustworthy.
+ </message>
+ <message name="IDS_CERT_ERROR_VALIDITY_TOO_LONG_DESCRIPTION" desc="Description of the error page for a certificate whose validity period is too long">
+ The server certificate has a validity period that is too long.
+ </message>
+
+ <message name="IDS_CERT_ERROR_UNKNOWN_ERROR_DETAILS" desc="Details of the error page for an unknown ssl error">
+ An unknown error has occurred.
+ </message>
+ <message name="IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION" desc="Description of the error page for an unknown ssl error">
+ Unknown server certificate error.
+ </message>
+
+ <message name="IDS_CERT_ERROR_SUMMARY_PINNING_FAILURE_DETAILS" desc="Details of the error page for a certificate which doesn't match the built-in pins for that name">
+ The server presented a certificate that doesn't match built-in expectations. These expectations are included for certain, high-security websites in order to protect you.
+ </message>
+ <message name="IDS_CERT_ERROR_SUMMARY_PINNING_FAILURE_DESCRIPTION" desc="Description of the error page for a certificate which doesn't match the built-in pins for that name">
+ The server's certificate appears to be a forgery.
+ </message>
+
+ <if expr="_google_chrome">
+ <if expr="is_ios">
+ <message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by Chrome. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ </if>
+ <if expr="is_android">
+ <message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your device's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ </if>
+ <if expr="not is_ios and not is_android">
+ <message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your computer's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ </if>
+ </if>
+
+ <if expr="not _google_chrome">
+ <if expr="is_ios">
+ <message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by Chromium. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ </if>
+ <if expr="is_android">
+ <message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your device's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ </if>
+ <if expr="not is_ios and not is_android">
+ <message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your computer's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
+ </if>
+ </if>
+
+</grit-part> \ No newline at end of file
diff --git a/chromium/components/strings/BUILD.gn b/chromium/components/strings/BUILD.gn
index ab42b5a1ac4..8af6c467c25 100644
--- a/chromium/components/strings/BUILD.gn
+++ b/chromium/components/strings/BUILD.gn
@@ -4,8 +4,17 @@
import("//tools/grit/grit_rule.gni")
+group("strings") {
+ public_deps = [
+ ":components_chromium_strings",
+ ":components_google_chrome_strings",
+ ":components_strings",
+ ]
+}
+
# GYP version: components/components_strings.gyp:components_strings
-grit("strings") {
+# (generate_components_strings action)
+grit("components_strings") {
source = "../components_strings.grd"
outputs = [
"grit/components_strings.h",
@@ -64,4 +73,166 @@ grit("strings") {
"components_strings_zh-CN.pak",
"components_strings_zh-TW.pak",
]
+
+ if (is_ios) {
+ # iOS uses "pt" for pt-BR" and "es-MX" for "es-419".
+ outputs -= [
+ "components_strings_pt-BR.pak",
+ "components_strings_es-419.pak",
+ ]
+ outputs += [
+ "components_strings_pt.pak",
+ "components_strings_es-MX.pak",
+ ]
+ }
+}
+
+# GYP version: components/components_strings.gyp:components_strings
+# (generate_components_chromium_strings action)
+grit("components_chromium_strings") {
+ source = "../components_chromium_strings.grd"
+ outputs = [
+ "grit/components_chromium_strings.h",
+ "components_chromium_strings_am.pak",
+ "components_chromium_strings_ar.pak",
+ "components_chromium_strings_bg.pak",
+ "components_chromium_strings_bn.pak",
+ "components_chromium_strings_ca.pak",
+ "components_chromium_strings_cs.pak",
+ "components_chromium_strings_da.pak",
+ "components_chromium_strings_de.pak",
+ "components_chromium_strings_el.pak",
+ "components_chromium_strings_en-GB.pak",
+ "components_chromium_strings_en-US.pak",
+ "components_chromium_strings_es.pak",
+ "components_chromium_strings_es-419.pak",
+ "components_chromium_strings_et.pak",
+ "components_chromium_strings_fa.pak",
+ "components_chromium_strings_fake-bidi.pak",
+ "components_chromium_strings_fi.pak",
+ "components_chromium_strings_fil.pak",
+ "components_chromium_strings_fr.pak",
+ "components_chromium_strings_gu.pak",
+ "components_chromium_strings_he.pak",
+ "components_chromium_strings_hi.pak",
+ "components_chromium_strings_hr.pak",
+ "components_chromium_strings_hu.pak",
+ "components_chromium_strings_id.pak",
+ "components_chromium_strings_it.pak",
+ "components_chromium_strings_ja.pak",
+ "components_chromium_strings_kn.pak",
+ "components_chromium_strings_ko.pak",
+ "components_chromium_strings_lt.pak",
+ "components_chromium_strings_lv.pak",
+ "components_chromium_strings_ml.pak",
+ "components_chromium_strings_mr.pak",
+ "components_chromium_strings_ms.pak",
+ "components_chromium_strings_nl.pak",
+ "components_chromium_strings_nb.pak",
+ "components_chromium_strings_pl.pak",
+ "components_chromium_strings_pt-BR.pak",
+ "components_chromium_strings_pt-PT.pak",
+ "components_chromium_strings_ro.pak",
+ "components_chromium_strings_ru.pak",
+ "components_chromium_strings_sk.pak",
+ "components_chromium_strings_sl.pak",
+ "components_chromium_strings_sr.pak",
+ "components_chromium_strings_sv.pak",
+ "components_chromium_strings_sw.pak",
+ "components_chromium_strings_ta.pak",
+ "components_chromium_strings_te.pak",
+ "components_chromium_strings_th.pak",
+ "components_chromium_strings_tr.pak",
+ "components_chromium_strings_uk.pak",
+ "components_chromium_strings_vi.pak",
+ "components_chromium_strings_zh-CN.pak",
+ "components_chromium_strings_zh-TW.pak",
+ ]
+
+ if (is_ios) {
+ # iOS uses "pt" for pt-BR" and "es-MX" for "es-419".
+ outputs -= [
+ "components_chromium_strings_pt-BR.pak",
+ "components_chromium_strings_es-419.pak",
+ ]
+ outputs += [
+ "components_chromium_strings_pt.pak",
+ "components_chromium_strings_es-MX.pak",
+ ]
+ }
+}
+
+# GYP version: components/components_strings.gyp:components_strings
+# (generate_components_google_chrome_strings action)
+grit("components_google_chrome_strings") {
+ source = "../components_google_chrome_strings.grd"
+ outputs = [
+ "grit/components_google_chrome_strings.h",
+ "components_google_chrome_strings_am.pak",
+ "components_google_chrome_strings_ar.pak",
+ "components_google_chrome_strings_bg.pak",
+ "components_google_chrome_strings_bn.pak",
+ "components_google_chrome_strings_ca.pak",
+ "components_google_chrome_strings_cs.pak",
+ "components_google_chrome_strings_da.pak",
+ "components_google_chrome_strings_de.pak",
+ "components_google_chrome_strings_el.pak",
+ "components_google_chrome_strings_en-GB.pak",
+ "components_google_chrome_strings_en-US.pak",
+ "components_google_chrome_strings_es.pak",
+ "components_google_chrome_strings_es-419.pak",
+ "components_google_chrome_strings_et.pak",
+ "components_google_chrome_strings_fa.pak",
+ "components_google_chrome_strings_fake-bidi.pak",
+ "components_google_chrome_strings_fi.pak",
+ "components_google_chrome_strings_fil.pak",
+ "components_google_chrome_strings_fr.pak",
+ "components_google_chrome_strings_gu.pak",
+ "components_google_chrome_strings_he.pak",
+ "components_google_chrome_strings_hi.pak",
+ "components_google_chrome_strings_hr.pak",
+ "components_google_chrome_strings_hu.pak",
+ "components_google_chrome_strings_id.pak",
+ "components_google_chrome_strings_it.pak",
+ "components_google_chrome_strings_ja.pak",
+ "components_google_chrome_strings_kn.pak",
+ "components_google_chrome_strings_ko.pak",
+ "components_google_chrome_strings_lt.pak",
+ "components_google_chrome_strings_lv.pak",
+ "components_google_chrome_strings_ml.pak",
+ "components_google_chrome_strings_mr.pak",
+ "components_google_chrome_strings_ms.pak",
+ "components_google_chrome_strings_nl.pak",
+ "components_google_chrome_strings_nb.pak",
+ "components_google_chrome_strings_pl.pak",
+ "components_google_chrome_strings_pt-BR.pak",
+ "components_google_chrome_strings_pt-PT.pak",
+ "components_google_chrome_strings_ro.pak",
+ "components_google_chrome_strings_ru.pak",
+ "components_google_chrome_strings_sk.pak",
+ "components_google_chrome_strings_sl.pak",
+ "components_google_chrome_strings_sr.pak",
+ "components_google_chrome_strings_sv.pak",
+ "components_google_chrome_strings_sw.pak",
+ "components_google_chrome_strings_ta.pak",
+ "components_google_chrome_strings_te.pak",
+ "components_google_chrome_strings_th.pak",
+ "components_google_chrome_strings_tr.pak",
+ "components_google_chrome_strings_uk.pak",
+ "components_google_chrome_strings_vi.pak",
+ "components_google_chrome_strings_zh-CN.pak",
+ "components_google_chrome_strings_zh-TW.pak",
+ ]
+
+ if (is_ios) {
+ # iOS uses "pt" for pt-BR" and "es-MX" for "es-419".
+ outputs -= [
+ "components_google_chrome_strings_pt-BR.pak",
+ "components_google_chrome_strings_es-419.pak",
+ ]
+ outputs += [
+ "components_google_chrome_strings_pt.pak",
+ "components_google_chrome_strings_es-MX.pak",
+ ]
+ }
}
diff --git a/chromium/components/strings/components_chromium_strings_am.xtb b/chromium/components/strings/components_chromium_strings_am.xtb
new file mode 100644
index 00000000000..27cca639bdc
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_am.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="am">
+<translation id="130631256467250065">ለውጦችዎ መሣሪያዎን ዳግም በሚያስጀምሩበት ቀጣዩ ጊዜ ላይ ይተገበራሉ።</translation>
+<translation id="4404275227760602850">ወደ Chromium ምናሌ &gt; ቅንብሮች &gt; (የላቁ) ግላዊነት ይሂዱ
+ እና «የገጽ ንብረቶችን ቅድሚያ አስመጣ»ን ያሰናክሉ።
+ ይሄ ችግሩን ካልፈታው ለተሻሻለ አፈጻጸም ይህን አማራጭ 
+ ዳግም ማንቃት እንመክራለን።</translation>
+<translation id="6613594504749178791">ለውጦችዎ Chromium በሚያስጀምሩበት ቀጣዩ ጊዜ ላይ ይተገበራሉ።</translation>
+<translation id="7861509383340276692">ወደ
+ የChromium ምናሌ &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ ይሂዱና «<ph name="NO_PREFETCH_DESCRIPTION" />»ን አይምረጡ።
+ ይሄ ችግሩን ካልፈታው ለተሻሻለ አፈጻጸም ይህን አማራጭ እንደገና መምረጥ እንመክራለን።</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_ar.xtb b/chromium/components/strings/components_chromium_strings_ar.xtb
new file mode 100644
index 00000000000..76b352da773
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_ar.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ar">
+<translation id="130631256467250065">تسري التغييرات في المرة التالية التي تعيد فيها تشغيل الجهاز.</translation>
+<translation id="4404275227760602850">‏انتقل إلى قائمة Chromium &gt; الإعدادات&gt; خصوصية (متقدمة)
+ وعطّل "موارد صفحة الجلب المسبق."
+ إذا لم يعمل هذا على حل المشكلة، نوصي بإعادة تمكين هذا الخيار
+ مرة أخرى من أجل أداء أفضل.</translation>
+<translation id="6613594504749178791">‏ستسري التغييرات في المرة التالية التي تعيد فيها تشغيل Chromium.</translation>
+<translation id="7861509383340276692">‏انتقل إلى
+ قائمة Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ وألغ تحديد "<ph name="NO_PREFETCH_DESCRIPTION" />"
+ في حالة ما إذا لم يؤد ذلك إلى حل المشكلة، نوصي بتحديد هذا الخيار
+ مرة أخرى من أجل أداء أفضل.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_bg.xtb b/chromium/components/strings/components_chromium_strings_bg.xtb
new file mode 100644
index 00000000000..150f3d3e554
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_bg.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="bg">
+<translation id="130631256467250065">Промените ви ще влязат в сила следващия път, когато рестартирате устройството си.</translation>
+<translation id="4404275227760602850">Отворете менюто на Chromium &gt; „Настройки“ &gt; „Поверителност“ (под „Разширени“)
+и деактивирайте опцията за предварително зареждане на ресурсите на страниците.
+Ако това не реши проблема, препоръчваме ви да я активирате отново,
+за да подобрите ефективността.</translation>
+<translation id="6613594504749178791">Промените ви ще влязат в сила следващия път, когато стартирате отново Chromium.</translation>
+<translation id="7861509383340276692">Отворете
+менюто на Chromium &gt;
+„<ph name="SETTINGS_TITLE" />“
+&gt;
+„<ph name="ADVANCED_TITLE" />“
+и премахнете отметката от „<ph name="NO_PREFETCH_DESCRIPTION" />“.
+Ако това не реши проблема, препоръчваме ви да изберете отново тази опция,
+за да подобрите ефективността.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_bn.xtb b/chromium/components/strings/components_chromium_strings_bn.xtb
new file mode 100644
index 00000000000..52d8dc487b5
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_bn.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="bn">
+<translation id="130631256467250065">পরের বার আপনি আপনার ডিভাইস পুনরারম্ভ করলে আপনার পরিবর্তনগুলি প্রভাবী হবে৷</translation>
+<translation id="4404275227760602850">Chromium মেনুতে যান &gt; সেটিংস &gt; (উন্নত) গোপনীয়তা
+ এবং "পৃষ্ঠার সংস্থান আনয়ন করা" অক্ষম করুন৷
+ যদি এটি সমস্যাটির সমাধান না করে, তাহলে উন্নত কার্য সম্পাদনার জন্য পুনরায়
+ এই বিকল্পটি নির্বাচন করা আমরা সুপারিশ করি৷</translation>
+<translation id="6613594504749178791">আপনার পরিবর্তনগুলি পরবর্তী সময় আপনি Chromium পুনরায় চালু হলে ফলপ্রদ হবে৷</translation>
+<translation id="7861509383340276692">Chromium মেনুতে
+ যান &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ এবং অনির্বাচন করুন "<ph name="NO_PREFETCH_DESCRIPTION" />৷"
+ যদি এটি সমস্যাটির সমাধান না করে, তাহলে উন্নত কার্য সম্পাদনার জন্য পুনরায় এই বিকল্পটি নির্বাচন করা সুপারিশ আমরা করি৷</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_ca.xtb b/chromium/components/strings/components_chromium_strings_ca.xtb
new file mode 100644
index 00000000000..6540b230aae
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_ca.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ca">
+<translation id="130631256467250065">Els canvis es faran efectius la propera vegada que reinicieu el dispositiu.</translation>
+<translation id="4404275227760602850">Aneu al Menú de Chromium &gt; Configuració &gt; (Avançada) Privadesa
+ i desmarqueu "Baixa prèviament els recursos de la pàgina".
+ Si el problema no es resol, us recomanem que torneu a activar
+ aquesta opció per obtenir un millor rendiment.</translation>
+<translation id="6613594504749178791">Els canvis s'aplicaran la propera vegada que reinicieu Chromium.</translation>
+<translation id="7861509383340276692">Aneu al
+ menú de Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ i desmarqueu <ph name="NO_PREFETCH_DESCRIPTION" />.
+ Si això no resol el problema, us recomanem que torneu a seleccionar
+ aquesta opció per obtenir un rendiment millorat.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_cs.xtb b/chromium/components/strings/components_chromium_strings_cs.xtb
new file mode 100644
index 00000000000..f82c2e38a59
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_cs.xtb
@@ -0,0 +1,8 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="cs">
+<translation id="130631256467250065">Změny se projeví po příštím restartu zařízení.</translation>
+<translation id="4404275227760602850">Přejděte do nabídky Chromium &gt; Nastavení &gt; (Rozšířené) Ochrana soukromí a zrušte výběr možnosti Předvídání síťových akcí. Pokud to však problém nevyřeší, doporučujeme vám tuto možnost znovu vybrat (za účelem zlepšení výkonu).</translation>
+<translation id="6613594504749178791">Změny se projeví po příštím restartu prohlížeče Chromium.</translation>
+<translation id="7861509383340276692">Přejděte do nabídky Chromium &gt; <ph name="SETTINGS_TITLE" /> &gt; <ph name="ADVANCED_TITLE" /> a zrušte výběr možnosti <ph name="NO_PREFETCH_DESCRIPTION" />. Pokud to však problém nevyřeší, doporučujeme vám tuto možnost znovu vybrat (za účelem zlepšení výkonu).</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_da.xtb b/chromium/components/strings/components_chromium_strings_da.xtb
new file mode 100644
index 00000000000..99a0366ddb5
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_da.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="da">
+<translation id="130631256467250065">Dine ændringer træder i kraft, næste gang du genstarter din enhed.</translation>
+<translation id="4404275227760602850">Gå til Chromium-menuen &gt; Indstillinger &gt; (Avanceret) Privatliv,
+ og fjern markeringen af "Hent sideressourcer på forhånd".
+ Hvis det ikke løser problemet, bør du markere dette afkrydsningsfelt
+ igen for at forbedre effektiviteten.</translation>
+<translation id="6613594504749178791">Dine ændringer træder i kraft, næste gang du genstarter Chromium.</translation>
+<translation id="7861509383340276692">Gå til
+ Chromium-menuen &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ og fjern markeringen af "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Hvis det ikke løser problemet, bør du markere dette afkrydsningsfelt
+ igen for at forbedre effektiviteten.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_de.xtb b/chromium/components/strings/components_chromium_strings_de.xtb
new file mode 100644
index 00000000000..57ae3eaa8cf
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_de.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="de">
+<translation id="130631256467250065">Ihre Änderungen werden beim nächsten Neustart wirksam.</translation>
+<translation id="4404275227760602850">Öffnen Sie das Chromium-Menü &gt; Einstellungen &gt; (Erweitert) Datenschutz
+ und deaktivieren Sie die Option "Vorabruf von Seitenressourcen".
+ Falls das Problem hierdurch nicht behoben wird, empfehlen wir,
+ diese Option für eine verbesserte Leistung wieder zu aktivieren.</translation>
+<translation id="6613594504749178791">Ihre Änderungen werden beim nächsten Neustart von Chromium wirksam.</translation>
+<translation id="7861509383340276692">Öffnen Sie
+ das Chromium-Menü &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ und deaktivieren Sie "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Falls das Problem nicht dadurch verursacht wurde, empfehlen wir,
+ diese Option für eine verbesserte Leistung wieder zu aktivieren.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_el.xtb b/chromium/components/strings/components_chromium_strings_el.xtb
new file mode 100644
index 00000000000..69ac3283c0b
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_el.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="el">
+<translation id="130631256467250065">Οι αλλαγές σας θα εφαρμοστούν την επόμενη φορά που θα επανεκκινήσετε τη συσκευή σας.</translation>
+<translation id="4404275227760602850">Μεταβείτε στο μενού του Chromium &gt; Ρυθμίσεις &gt; (Για προχωρημένους) Απόρρητο
+ και απενεργοποιήστε την "Πρόωρη λήψη πόρων."
+ Αν δεν επιλυθεί το πρόβλημά σας με αυτόν τον τρόπο, σάς συνιστούμε να ενεργοποιήσετε ξανά αυτή την επιλογή
+ για βελτιωμένες επιδόσεις.</translation>
+<translation id="6613594504749178791">Οι αλλαγές που πραγματοποιήσατε θα ισχύσουν την επόμενη φορά που θα εκκινήσετε το Chromium.</translation>
+<translation id="7861509383340276692">Μεταβείτε
+ στο μενού του Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ και καταργήστε την επιλογή "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Εάν με αυτόν τον τρόπο δεν επιλύεται το ζήτημά σας, συνιστούμε
+ να ενεργοποιήσετε ξανά αυτήν την επιλογή για βελτιωμένη απόδοση.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_en-GB.xtb b/chromium/components/strings/components_chromium_strings_en-GB.xtb
new file mode 100644
index 00000000000..4ab2e6d6396
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_en-GB.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="en-GB">
+<translation id="130631256467250065">Your changes will take effect the next time that you restart your device.</translation>
+<translation id="4404275227760602850">Go to the Chromium menu &gt; Settings &gt; (Advanced) Privacy
+ and disable "Prefetch page resources".
+ If this does not resolve the issue, we recommend re-enabling this option
+ again for improved performance.</translation>
+<translation id="6613594504749178791">Your changes will take effect the next time you relaunch Chromium.</translation>
+<translation id="7861509383340276692">Go to
+ the Chromium menu &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ and deselect "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ If this does not resolve the issue, we recommend selecting this option
+ again for improved performance.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_es-419.xtb b/chromium/components/strings/components_chromium_strings_es-419.xtb
new file mode 100644
index 00000000000..d84cea541c0
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_es-419.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="es-419">
+<translation id="130631256467250065">Los cambios se aplicarán la próxima vez que reinicies el dispositivo.</translation>
+<translation id="4404275227760602850">Ve al menú de Chromium &gt; Configuración &gt; (Avanzada) Privacidad
+ e inhabilita la opción para solicitar los recursos de la página previamente.
+ Si el problema persiste, vuelve a habilitar esta opción
+ para obtener un mejor rendimiento.</translation>
+<translation id="6613594504749178791">Los cambios se aplicarán la próxima vez que inicies Chromium.</translation>
+<translation id="7861509383340276692">Ve
+ al menú de Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ y anula la selección de "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Si esto no resuelve el problema, vuelve a habilitar esta opción
+ para obtener un mejor desempeño.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_es.xtb b/chromium/components/strings/components_chromium_strings_es.xtb
new file mode 100644
index 00000000000..bc6a9841176
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_es.xtb
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="es">
+<translation id="130631256467250065">Los cambios se aplicarán la próxima vez que reinicies el dispositivo.</translation>
+<translation id="4404275227760602850">Accede al menú de Chromium, selecciona Ajustes, haz clic en Privacidad (Avanzados) e inhabilita la opción de cargar previamente recursos de página. Si esto no soluciona el problema, te recomendamos que vuelvas a habilitar esta opción para mejorar el rendimiento.</translation>
+<translation id="6613594504749178791">Los cambios se aplicarán la próxima vez que reinicies Chromium.</translation>
+<translation id="7861509383340276692">Accede al
+ menú de Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ y desactiva la opción "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Si esto no soluciona el problema, te recomendamos que vuelvas a seleccionar esta opción
+ para conseguir un mejor rendimiento.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_et.xtb b/chromium/components/strings/components_chromium_strings_et.xtb
new file mode 100644
index 00000000000..4d14e4a34d6
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_et.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="et">
+<translation id="130631256467250065">Muudatused jõustuvad järgmine kord, kui seadme taaskäivitate.</translation>
+<translation id="4404275227760602850">Avage Chromiumi menüü &gt; Seaded &gt; (Täpsem) Privaatsus
+ ja keelake valik „Lehe ressursside eellaadimine”.
+ Kui see probleemi ei lahenda, soovitame selle valiku toimivuse
+ parandamiseks uuesti lubada.</translation>
+<translation id="6613594504749178791">Teie muudatused jõustuvad järgmine kord, kui Chromiumi taaskäivitate.</translation>
+<translation id="7861509383340276692">Avage
+ Chromiumi menüü &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ ja tühistage valik „<ph name="NO_PREFETCH_DESCRIPTION" />”.
+ Kui see probleemi ei lahenda, soovitame selle valiku
+ toimivuse parandamiseks uuesti teha.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_fa.xtb b/chromium/components/strings/components_chromium_strings_fa.xtb
new file mode 100644
index 00000000000..9dc929d5816
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_fa.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fa">
+<translation id="130631256467250065">تغییرات بار بعد که دستگاه راه‌اندازی می‌شود اعمال می‌شوند.</translation>
+<translation id="4404275227760602850">‏به منوی Chromium &gt; تنظیمات &gt; (پیشرفته) حریم خصوصی
+ بروید و «واکشی منابع صفحه» را غیرفعال کنید.
+ درصورتی‌که با این کار مشکل حل نشد، توصیه می‌کنیم برای عملکرد بهبودیافته،
+ این گزینه را دوباره فعال کنید.</translation>
+<translation id="6613594504749178791">‏دفعه بعدی که Chromium را مجدداً راه‌اندازی می‌کنید، این تغییرات اعمال می‌شوند.</translation>
+<translation id="7861509383340276692">‏به
+ منوی Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ بروید و علامت «<ph name="NO_PREFETCH_DESCRIPTION" />» را بردارید.
+ درصورتی‌که با این کار مشکل حل نشد، توصیه می‌کنیم برای عملکرد بهبودیافته،
+  این گزینه را دوباره انتخاب کنید.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_fi.xtb b/chromium/components/strings/components_chromium_strings_fi.xtb
new file mode 100644
index 00000000000..6b8b30959d5
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_fi.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fi">
+<translation id="130631256467250065">Muutokset tulevat voimaan, kun käynnistät laitteen seuraavan kerran.</translation>
+<translation id="4404275227760602850">Avaa Chromium-valikko &gt; Asetukset &gt; Tietosuoja (Lisäasetukset)
+ ja poista valinta kohdasta Hae valmiiksi sivun resurssit.
+ Jos ongelma ei ratkea, valitse tämä vaihtoehto uudelleen suorituskyvyn
+ parantamiseksi.</translation>
+<translation id="6613594504749178791">Muutokset tulevat voimaan, kun käynnistät Chromiumin seuraavan kerran.</translation>
+<translation id="7861509383340276692">Avaa
+ Chromium-valikko &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ ja poista valinta kohdasta <ph name="NO_PREFETCH_DESCRIPTION" />.
+ Jos ongelma ei ratkea, valitse tämä vaihtoehto
+ uudelleen suorituskyvyn parantamiseksi.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_fil.xtb b/chromium/components/strings/components_chromium_strings_fil.xtb
new file mode 100644
index 00000000000..8d2da7ef3c6
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_fil.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fil">
+<translation id="130631256467250065">Magkakabisa ang iyong mga pagbabago sa susunod na i-restart ang iyong device.</translation>
+<translation id="4404275227760602850">Pumunta sa menu ng Chromium &gt; Mga Setting &gt; (Advanced) Privacy
+ at i-disable ang "I-prefetch ang mga mapagkukunan ng page."
+ Kung hindi nito malutas ang isyu, inirerekomenda naming muling
+ i-enable ang opsyong ito para sa mas mahusay na pagganap.</translation>
+<translation id="6613594504749178791">Magkakabisa ang iyong mga pagbabago sa susunod na ilunsad mong muli ang Chromium.</translation>
+<translation id="7861509383340276692">Pumunta
+ sa menu ng Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ at alisin sa pagkakapili ang "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Kung hindi nito malulutas ang isyu, inirerekomenda naming piliing muli ang opsyong ito
+ para sa pinahusay na pagganap.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_fr.xtb b/chromium/components/strings/components_chromium_strings_fr.xtb
new file mode 100644
index 00000000000..229a1abf2d1
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_fr.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fr">
+<translation id="130631256467250065">Vos modifications seront prises en compte au prochain démarrage de l'appareil.</translation>
+<translation id="4404275227760602850">Accédez au menu Chromium &gt; Paramètres &gt; (Avancés) Confidendialité,
+ puis désactivez "Prélire les ressources de pages".
+ Si le problème persiste, nous vous conseillons de réactiver cette option
+ pour des performances optimales.</translation>
+<translation id="6613594504749178791">Vos modifications seront prises en compte au prochain redémarrage de Chromium.</translation>
+<translation id="7861509383340276692">Accédez
+ au menu Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />,
+ puis désélectionnez "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Si le problème persiste, nous vous conseillons de
+ réactiver cette option pour des performances optimales.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_gu.xtb b/chromium/components/strings/components_chromium_strings_gu.xtb
new file mode 100644
index 00000000000..909f7a2dfcd
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_gu.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="gu">
+<translation id="130631256467250065">તમારા ફેરફારો તમે આગલી વખતે તમારા ઉપકરણને ફરી પ્રારંભ કરશો ત્યારે પ્રભાવમાં આવશે.</translation>
+<translation id="4404275227760602850">Chromium મેનૂ &gt; સેટિંગ્સ &gt; (વિગતવાર) ગોપનીયતા પર જાઓ
+ અને "પૃષ્ઠ સંસાધનોનું પૂર્વ આનયન કરો" ને અક્ષમ કરો.
+ જો આનાથી સમસ્યા ઉકેલાતી નથી, તો અમે સુધારેલ પ્રદર્શન માટે ફરીથી આ વિકલ્પને
+ ફરીથી-સક્ષમ કરવાની ભલામણ કરીએ છીએ.</translation>
+<translation id="6613594504749178791">તમારા ફેરફારો તમે આગલી વખતે Chromium ફરીથી લોંચ કરશો ત્યારે પ્રભાવમાં આવશે.</translation>
+<translation id="7861509383340276692">Chromium મેનૂ &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ પર જાઓ અને "<ph name="NO_PREFETCH_DESCRIPTION" />" પસંદગીને હટાવો.
+ જો આનાથી સમસ્યા ઉકેલાતી નથી, તો અમે સુધારેલ પ્રદર્શન માટે ફરીથી આ વિકલ્પને પસંદ કરવાની
+ ભલામણ કરીએ છીએ.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_hi.xtb b/chromium/components/strings/components_chromium_strings_hi.xtb
new file mode 100644
index 00000000000..0800776b8d4
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_hi.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hi">
+<translation id="130631256467250065">अगली बार अपना डिवाइस पुन: प्रारंभ करने पर आपके परिवर्तन प्रभावी हो जाएंगे.</translation>
+<translation id="4404275227760602850">क्रोमियम मेनू &gt; सेटिंग &gt; (उन्‍नत) गोपनीयता पर जाएं
+ और "पृष्‍ठ संसाधनों को प्रीफ़ेच करें" को अक्षम करें.
+ यदि इससे समस्‍या हल नहीं होती, तो बेहतर प्रदर्शन के लिए हम इस विकल्‍प को पुन:
+ सक्षम करने की अनुशंसा करते हैं.</translation>
+<translation id="6613594504749178791">अगली बार आपके द्वारा क्रोमियम पुन: लॉन्‍च करने पर आपके परिवर्तन प्रभावी होंगे.</translation>
+<translation id="7861509383340276692">क्रोमियम
+ मेनू &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ पर जाएं और "<ph name="NO_PREFETCH_DESCRIPTION" />" का चयन हटाएं.
+ यदि इससे समस्‍या हल नहीं होती, तो बेहतर प्रदर्शन के लिए हम इस विकल्‍प को पुन: चुनने की
+ अनुशंसा करते हैं.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_hr.xtb b/chromium/components/strings/components_chromium_strings_hr.xtb
new file mode 100644
index 00000000000..0003f56c19d
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_hr.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hr">
+<translation id="130631256467250065">Promjene će početi vrijediti sljedeći put kad ponovo pokrenete uređaj.</translation>
+<translation id="4404275227760602850">Otvorite izbornik Chromiuma &gt; Postavke &gt; (Napredno) Privatnost
+ i onemogućite "Unaprijed dohvati resurse stranice".
+ Ako se time ne riješi poteškoća, preporučujemo da ponovo omogućite tu opciju
+ radi bolje izvedbe.</translation>
+<translation id="6613594504749178791">Promjene će početi vrijediti sljedeći put kad ponovo pokrenete Chromium.</translation>
+<translation id="7861509383340276692">Otvorite
+ izbornik Chromiuma &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ pa poništite odabir stavke "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Ako se time ne riješi poteškoća, preporučujemo da ponovo odaberete tu opciju
+ radi bolje izvedbe.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_hu.xtb b/chromium/components/strings/components_chromium_strings_hu.xtb
new file mode 100644
index 00000000000..b169d93b007
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_hu.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hu">
+<translation id="130631256467250065">A módosítások az eszköz következő újraindításakor lépnek életbe.</translation>
+<translation id="4404275227760602850">Nyissa meg a Chromium-menü &gt; Beállítások &gt; (Speciális) Adatvédelem menüelemet,
+ és tiltsa le az „Oldalforrások előzetes lehívása” beállítást.
+ Ha ettől nem szűnik meg a probléma, javasoljuk, hogy engedélyezze újra ezt a lehetőséget
+ a jobb teljesítmény érdekében.</translation>
+<translation id="6613594504749178791">Módosításai a Chromium újraindítása után lépnek érvénybe.</translation>
+<translation id="7861509383340276692">Lépjen ide:
+ Chromium menü &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />,
+ és törölje a jelet a(z) „<ph name="NO_PREFETCH_DESCRIPTION" />” jelölőnégyzetből.
+ Ha ettől nem szűnik meg a probléma, javasoljuk, hogy jelölje be ismét ezt a lehetőséget a jobb teljesítmény érdekében.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_id.xtb b/chromium/components/strings/components_chromium_strings_id.xtb
new file mode 100644
index 00000000000..c577892dc64
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_id.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="id">
+<translation id="130631256467250065">Perubahan Anda akan diterapkan pada saat Anda nanti menyalakan ulang perangkat.</translation>
+<translation id="4404275227760602850">Buka menu Chromium &gt; Setelan &gt; (Lanjutan) Privasi
+ dan nonaktifkan "Ambil sumber daya laman lebih dahulu".
+ Jika hal ini tidak menyelesaikan masalah, sebaiknya aktifkan opsi ini
+ lagi untuk kinerja yang ditingkatkan.</translation>
+<translation id="6613594504749178791">Perubahan Anda akan berlaku saat berikutnya Anda membuka Chromium.</translation>
+<translation id="7861509383340276692">Buka
+ menu Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ dan batalkan pilihan "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Jika hal ini tidak menyelesaikan masalah, sebaiknya pilih lagi opsi ini
+ untuk meningkatkan kinerja.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_it.xtb b/chromium/components/strings/components_chromium_strings_it.xtb
new file mode 100644
index 00000000000..37cb696d398
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_it.xtb
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="it">
+<translation id="130631256467250065">Le modifiche verranno applicate al successivo riavvio del dispositivo.</translation>
+<translation id="4404275227760602850">Seleziona il menu Chromium &gt; Impostazioni &gt; (Avanzate) Privacy e disattiva l'opzione "Precarica risorse delle pagine".
+Se il problema non si risolve, dovresti riattivare questa opzione per ottenere prestazioni migliori.</translation>
+<translation id="6613594504749178791">Le modifiche verranno applicate al prossimo riavvio di Chromium.</translation>
+<translation id="7861509383340276692">Seleziona il menu Chromium &gt; <ph name="SETTINGS_TITLE" /> &gt; <ph name="ADVANCED_TITLE" /> e deseleziona "<ph name="NO_PREFETCH_DESCRIPTION" />".
+Se il problema non si risolve, dovresti riselezionare questa opzione per ottenere prestazioni migliori.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_iw.xtb b/chromium/components/strings/components_chromium_strings_iw.xtb
new file mode 100644
index 00000000000..0f450dbc9f5
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_iw.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="iw">
+<translation id="130631256467250065">השינויים ייכנסו לתוקף בפעם הבאה שתפעיל מחדש את המכשיר.</translation>
+<translation id="4404275227760602850">‏עבור לתפריט Chromium &gt; הגדרות &gt; (מתקדם) פרטיות
+ והשבת את 'בצע אחזור מוקדם למשאבי דף'.
+ אם פעולה זו אינה פותרת את הבעיה, מומלץ להפעיל מחדש את האפשרות הזו
+ כדי לשפר את הביצועים.</translation>
+<translation id="6613594504749178791">‏השינויים שביצעת ייכנסו לתוקף בפעם הבאה שתפעיל מחדש את Chromium‏.</translation>
+<translation id="7861509383340276692">‏עבור אל
+ תפריט Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ ובטל את הבחירה באפשרות '<ph name="NO_PREFETCH_DESCRIPTION" />'.
+ אם פעולה זו אינה פותרת את הבעיה, מומלץ לבחור שוב באפשרות זו
+ לקבלת ביצועים משופרים.</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
new file mode 100644
index 00000000000..a10ee2ab647
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_ja.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ja">
+<translation id="130631256467250065">変更内容は、次回の端末の起動時に反映されます。</translation>
+<translation id="4404275227760602850">Chromium メニュー &gt; [設定] &gt; [(詳細)プライバシー] の順に移動して、
+ [ページリソースのプリフェッチ] を無効にします。
+ 上記を行っても問題が解決しない場合は、パフォーマンス向上のため
+ このオプションを再び有効にすることをおすすめします。</translation>
+<translation id="6613594504749178791">変更内容は次に Chromium を再起動したときに有効になります。</translation>
+<translation id="7861509383340276692">Chromium メニュー &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ の順に移動して、[<ph name="NO_PREFETCH_DESCRIPTION" />] をオフにします。
+ 上記を行っても問題が解決しない場合は、パフォーマンス向上のため
+ このオプションを再びオンにすることをおすすめします。</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_kn.xtb b/chromium/components/strings/components_chromium_strings_kn.xtb
new file mode 100644
index 00000000000..61aadf99f5e
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_kn.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="kn">
+<translation id="130631256467250065">ನಿಮ್ಮ ಸಾಧನವನ್ನು ನೀವು ಮುಂದಿನ ಬಾರಿ ಮರುಪ್ರಾರಂಭಿಸಿದಾಗ ನಿಮ್ಮ ಬದಲಾವಣೆಗಳು ಕಾರ್ಯಗತಗೊಳ್ಳುತ್ತವೆ.</translation>
+<translation id="4404275227760602850">Chromium ಮೆನು &gt; ಸೆಟ್ಟಿಂಗ್‌ಗಳು &gt; (ಸುಧಾರಿತ) ಗೌಪ್ಯತೆಗೆ ಹೋಗಿ
+ ಮತ್ತು "ಪುಟ ಸಂಪನ್ಮೂಲಗಳನ್ನು ಪೂರ್ವಪಡೆಯುವಿಕೆ" ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ
+ ಒಂದು ವೇಳೆ ಇದು ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸದಿದ್ದರೆ, ಸುಧಾರಿತ ಕಾರ್ಯಾಚರಣೆಗಾಗಿ ಮತ್ತೊಮ್ಮೆ
+ ಈ ಆಯ್ಕೆಯನ್ನು ಮರುಸಕ್ರಿಯಗೊಳಿಸುವಂತೆ ನಾವು ಶಿಫಾರಸು ಮಾಡುತ್ತೇವೆ.</translation>
+<translation id="6613594504749178791">ನೀವು ಮುಂದಿನ ಬಾರಿ Chromium ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿದಾಗ ನಿಮ್ಮ ಬದಲಾವಣೆಗಳು ಕಾರ್ಯಗತಗೊಳ್ಳುತ್ತವೆ.</translation>
+<translation id="7861509383340276692">ಇದಕ್ಕೆ ಹೋಗಿ
+ Chromium ಮೆನು &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ ಮತ್ತು "<ph name="NO_PREFETCH_DESCRIPTION" />" ಆಯ್ಕೆ ರದ್ದುಮಾಡಿ.
+ ಒಂದು ವೇಳೆ ಇದು ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸದಿದ್ದರೆ, ಸುಧಾರಿತ ಕಾರ್ಯಾಚರಣೆಗಾಗಿ ಮತ್ತೊಮ್ಮೆ
+ ಈ ಆಯ್ಕೆಯನ್ನು ಆಯ್ಕೆ ಮಾಡುವಂತೆ ನಾವು ಶಿಫಾರಸು ಮಾಡುತ್ತೇವೆ.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_ko.xtb b/chromium/components/strings/components_chromium_strings_ko.xtb
new file mode 100644
index 00000000000..4b5c6ba8dd0
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_ko.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ko">
+<translation id="130631256467250065">기기를 다시 시작할 때 변경사항이 적용됩니다.</translation>
+<translation id="4404275227760602850">Chromium 메뉴 &gt; 설정 &gt; (고급)개인정보로
+ 이동하여 '페이지 리소스 프리패치'를 사용 중지합니다.
+ 그래도 문제가 해결되지 않으면 이 옵션을 다시 사용 설정하여
+ 성능을 개선해 보시기 바랍니다.</translation>
+<translation id="6613594504749178791">변경사항은 다음에 Chromium을 다시 시작할 때 적용됩니다.</translation>
+<translation id="7861509383340276692">Chromium 메뉴 &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ (으)로 이동하고 '<ph name="NO_PREFETCH_DESCRIPTION" />'을(를) 선택 취소합니다.
+ 그래도 문제가 해결되지 않으면 이 옵션을 다시 선택하여
+ 성능을 개선해 보시기 바랍니다.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_lt.xtb b/chromium/components/strings/components_chromium_strings_lt.xtb
new file mode 100644
index 00000000000..ef6b541b0db
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_lt.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="lt">
+<translation id="130631256467250065">Pakeitimai įsigalios kitą kartą iš naujo paleidus įrenginį.</translation>
+<translation id="4404275227760602850">Eikite į „Chromium“ meniu &gt; Nustatymai &gt; (Išplėstiniai) Privatumas
+ ir išjunkite parinktį „Iš anksto iškviesti puslapio išteklius“.
+ Jei tai atlikus problema išlieka, rekomenduojame iš naujo įgalinti šią parinktį,
+ kad pagerėtų našumas.</translation>
+<translation id="6613594504749178791">Pakeitimai įsigalios kitą kartą iš naujo paleidus „Chromium“.</translation>
+<translation id="7861509383340276692">Eikite į
+ „Chromium“ meniu &gt;
+ „<ph name="SETTINGS_TITLE" />“
+ &gt;
+ „<ph name="ADVANCED_TITLE" />“
+ ir panaikinkite „<ph name="NO_PREFETCH_DESCRIPTION" />“ pasirinkimą.
+ Jei tai atlikus problema išlieka, rekomenduojame vėl pasirinkti šią parinktį,
+ kad pagerėtų našumas.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_lv.xtb b/chromium/components/strings/components_chromium_strings_lv.xtb
new file mode 100644
index 00000000000..ebc7b2d9763
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_lv.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="lv">
+<translation id="130631256467250065">Izmaiņas stāsies spēkā nākamajā reizē, kad restartēsiet ierīci.</translation>
+<translation id="4404275227760602850">Atveriet Chromium izvēlni &gt; Iestatījumi &gt; (Papildu) Konfidencialitāte
+ un atspējojiet opciju “Sākotnēji iegūt lapu resursus”.
+ Ja problēma netiek novērsta, ieteicams atkārtoti iespējot šo opciju,
+ lai uzlabotu veiktspēju.</translation>
+<translation id="6613594504749178791">Izmaiņas stāsies spēkā, kad restartēsiet Chromium.</translation>
+<translation id="7861509383340276692">Atveriet
+ Chromium izvēlni &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ un noņemiet atzīmi no izvēles rūtiņas “<ph name="NO_PREFETCH_DESCRIPTION" />”.
+ Ja problēmu neizdodas novērst, ieteicams atkal atlasīt šo opciju,
+ lai uzlabotu veiktspēju.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_ml.xtb b/chromium/components/strings/components_chromium_strings_ml.xtb
new file mode 100644
index 00000000000..5f114be1589
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_ml.xtb
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ml">
+<translation id="130631256467250065">നിങ്ങൾ അടുത്ത തവണ ഉപകരണം പുനരാരംഭിക്കുമ്പോൾ മാറ്റങ്ങൾ പ്രാബല്യത്തിൽ വരും.</translation>
+<translation id="4404275227760602850">Chromium മെനു &gt; ക്രമീകരണം &gt; (വിപുലീകരിച്ചത്) സ്വകാര്യത എന്നതിലേക്ക് പോയി
+ ''പ്രീഫെച്ച് പേജ് ഉറവിടങ്ങൾ''പ്രവർത്തനരഹിതമാക്കുക.
+ ഇത് പ്രശ്‌നം പരിഹരിച്ചില്ലെങ്കിൽ, മെച്ചപ്പെട്ട പ്രവർത്തനത്തിനായി ഈ
+ ഓപ്‌ഷൻ വീണ്ടും പ്രവർത്തനക്ഷമമാക്കാൻ ഞങ്ങൾ ശുപാർശചെയ്യുന്നു.</translation>
+<translation id="6613594504749178791">നിങ്ങളുടെ മാറ്റങ്ങൾ അടുത്ത തവണ Chromium വീണ്ടും സമാരംഭിക്കുമ്പോൾ പ്രാബല്യത്തിൽ വരും.</translation>
+<translation id="7861509383340276692">Chromium മെനു &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" /> എന്നതിലേക്ക് പോയി
+ "<ph name="NO_PREFETCH_DESCRIPTION" />" തിരഞ്ഞെടുത്തത് മാറ്റുക.
+ ഇത് പ്രശ്‌നം പരിഹരിക്കുന്നില്ലെങ്കിൽ, മെച്ചപ്പെട്ട പ്രകടനത്തിനായി ഈ ഓപ്‌ഷൻ വീണ്ടും തിരഞ്ഞെടുക്കാൻ ഞങ്ങൾ ശുപാർശ ചെയ്യുന്നു.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_mr.xtb b/chromium/components/strings/components_chromium_strings_mr.xtb
new file mode 100644
index 00000000000..093c56714f1
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_mr.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="mr">
+<translation id="130631256467250065">आपण आपल्या डिव्हाइसचा पुढील वेळी पुनरारंभ कराल तेव्हा आपले बदल प्रभावी होतील.</translation>
+<translation id="4404275227760602850">Chromium मेनू &gt; सेटिंग्ज &gt; (प्रगत) गोपनीयता वर जा
+ आणि "पृष्ठ संसाधने अगोदर आणा" अक्षम करा.
+ यामुळे समस्येचे निराकरण होत नसल्यास, सुधारित कार्यप्रदर्शनासाठी हा पुन्हा या
+ पर्यायास पुन्हा-सक्षम करण्याची आम्ही शिफारस करतो.</translation>
+<translation id="6613594504749178791">आपण पुढल्या वेळी Chromium रीलाँच कराल तोपर्यंत आपले बदल प्रभावी होतील.</translation>
+<translation id="7861509383340276692">Chromium मेनू &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ वर जा आणि "<ph name="NO_PREFETCH_DESCRIPTION" />" ची निवड रद्द करा.
+ हे समस्‍येचे निराकरण करीत नसल्‍यास, आम्‍ही
+सुधारित कार्यप्रदर्शनासाठी पुन्हा
+ हा पर्याय निवडण्याची शिफारस करतो.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_ms.xtb b/chromium/components/strings/components_chromium_strings_ms.xtb
new file mode 100644
index 00000000000..fa3b0a5fe7b
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_ms.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ms">
+<translation id="130631256467250065">Perubahan anda akan dilaksanakan apabila anda memulakan semula peranti anda pada masa akan datang.</translation>
+<translation id="4404275227760602850">Pergi ke menu Chromium &gt; Tetapan &gt; (Lanjutan) Privasi
+ dan lumpuhkan "Praambil sumber halaman."
+ Jika tindakan ini tidak menyelesaikan isu ini, kami cadangkan agar mendayakan semula pilihan ini
+ sekali lagi untuk prestasi yang lebih baik.</translation>
+<translation id="6613594504749178791">Perubahan anda akan dilaksanakan apabila anda melancarkan semula Chromium pada masa hadapan.</translation>
+<translation id="7861509383340276692">Pergi ke
+ menu Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ dan nyahpilih "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Jika tindakan ini tidak menyelesaikan isu ini, kami cadangkan agar memilih pilihan ini
+ sekali lagi untuk prestasi yang dipertingkatkan.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_nl.xtb b/chromium/components/strings/components_chromium_strings_nl.xtb
new file mode 100644
index 00000000000..2744d867e7a
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_nl.xtb
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="nl">
+<translation id="130631256467250065">Je wijzigingen worden doorgevoerd wanneer je het apparaat opnieuw opstart.</translation>
+<translation id="4404275227760602850">Ga naar het Chromium-menu &gt; Instellingen &gt; (Geavanceerd) Privacy en schakel 'Paginabronnen prefetchen' uit. Als het probleem hiermee niet wordt opgelost, raden we je aan deze optie weer in te schakelen voor verbeterde prestaties.</translation>
+<translation id="6613594504749178791">Je wijzigingen worden toegepast wanneer je Chromium opnieuw start.</translation>
+<translation id="7861509383340276692">Ga naar
+ het Chromium-menu &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ en verwijder het vinkje bij '<ph name="NO_PREFETCH_DESCRIPTION" />'.
+ Als het probleem aanhoudt, adviseren we deze optie weer aan te
+ vinken voor betere prestaties.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_no.xtb b/chromium/components/strings/components_chromium_strings_no.xtb
new file mode 100644
index 00000000000..bb5ce0a847e
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_no.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="no">
+<translation id="130631256467250065">Endringene trer i kraft neste gang du starter enheten på nytt.</translation>
+<translation id="4404275227760602850">Gå til Chromium-menyen &gt; Innstillinger &gt; (Avansert) Personvern,
+ og slå av alternativet for henting av sideressurser på forhånd.
+ Hvis ikke dette løser problemet, bør du slå på dette alternativet
+ igjen for å bedre ytelsen.</translation>
+<translation id="6613594504749178791">Endringene dine trer i kraft neste gang du starter Chromium.</translation>
+<translation id="7861509383340276692">Gå til
+ Chromium-menyen &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ og fjern avmerkingen for «<ph name="NO_PREFETCH_DESCRIPTION" />».
+ Hvis dette ikke løser problemet, bør du aktivere dette alternativet
+ på nytt for bedre ytelse.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_pl.xtb b/chromium/components/strings/components_chromium_strings_pl.xtb
new file mode 100644
index 00000000000..88ba55b6af8
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_pl.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pl">
+<translation id="130631256467250065">Zmiany zostaną zastosowane przy następnym uruchomieniu urządzenia.</translation>
+<translation id="4404275227760602850">Wybierz kolejno menu Chromium &gt; Ustawienia &gt; (Zaawansowane) Prywatność
+ i wyłącz „Wstępnie pobieraj zasoby strony”.
+ Jeśli to nie rozwiąże problemu, zalecamy ponowne włączenie tej opcji,
+ by poprawić wydajność.</translation>
+<translation id="6613594504749178791">Zmiany zostaną zastosowane po ponownym uruchomieniu Chromium.</translation>
+<translation id="7861509383340276692">Wybierz
+ menu Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ i odznacz „<ph name="NO_PREFETCH_DESCRIPTION" />”.
+ Jeśli nie rozwiąże to problemu, zalecamy ponowne wybranie tej opcji,
+ by poprawić wydajność.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_pt-BR.xtb b/chromium/components/strings/components_chromium_strings_pt-BR.xtb
new file mode 100644
index 00000000000..5ee7edab063
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_pt-BR.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pt-BR">
+<translation id="130631256467250065">As alterações entrarão em vigor na próxima vez que você reiniciar o dispositivo.</translation>
+<translation id="4404275227760602850">Vá até o menu do Chromium &gt; Configurações &gt; (Avançado) Privacidade
+ e desative "Recursos de página de pré-chamada".
+ Se isso não resolver o problema, recomendamos que você reative essa opção
+ novamente para melhorar o desempenho.</translation>
+<translation id="6613594504749178791">As alterações entrarão em vigor na próxima vez que você reiniciar o Chromium.</translation>
+<translation id="7861509383340276692">Vá até
+ o menu do Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ e desmarque "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Se isso não resolver o problema, recomendamos que você selecione essa opção
+ novamente para melhorar o desempenho.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_pt-PT.xtb b/chromium/components/strings/components_chromium_strings_pt-PT.xtb
new file mode 100644
index 00000000000..71d04b36a55
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_pt-PT.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pt-PT">
+<translation id="130631256467250065">As alterações terão efeito da próxima vez que reiniciar o dispositivo.</translation>
+<translation id="4404275227760602850">Aceda ao menu do Chromium &gt; Definições &gt; Privacidade (avançada)
+ e desative "Registar previamente os recursos da página".
+ Se esta ação não resolver o problema, recomendamos que reative esta opção
+ novamente para melhorar o desempenho.</translation>
+<translation id="6613594504749178791">As alterações serão aplicadas da próxima vez que reiniciar o Chromium.</translation>
+<translation id="7861509383340276692">Aceda ao
+ menu Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ e desmarque "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Se isso não resolver o problema, recomendamos que selecione esta opção
+ novamente para um desempenho melhorado.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_ro.xtb b/chromium/components/strings/components_chromium_strings_ro.xtb
new file mode 100644
index 00000000000..8e52b2cc4fd
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_ro.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ro">
+<translation id="130631256467250065">Modificările dvs. se vor aplica următoarea dată când reporniți dispozitivul.</translation>
+<translation id="4404275227760602850">Accesează meniul Chromium &gt; Setări &gt; (Avansate) Confidențialitate
+ și dezactivează „Preia în avans resursele paginii.”
+ Dacă această acțiune nu rezolvă problema, îți recomandăm să reactivezi
+ această opțiune pentru îmbunătățirea performanței.</translation>
+<translation id="6613594504749178791">Modificările dvs. vor intra în vigoare următoarea dată când reporniți Chromium.</translation>
+<translation id="7861509383340276692">Accesează
+ meniul Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ și debifează „<ph name="NO_PREFETCH_DESCRIPTION" />”.
+ Dacă această acțiune nu rezolvă problema, îți recomandăm să selectezi din nou
+ această opțiune pentru performanță îmbunătățită.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_ru.xtb b/chromium/components/strings/components_chromium_strings_ru.xtb
new file mode 100644
index 00000000000..fa467c2dd15
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_ru.xtb
@@ -0,0 +1,8 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ru">
+<translation id="130631256467250065">Изменения вступят в силу после перезагрузки устройства.</translation>
+<translation id="4404275227760602850">Откройте меню Chromium, нажмите "Настройки &gt; Показать дополнительные настройки &gt; Личные данные" и отключите функцию "Запрашивать настройки и файлы для ускорения загрузки страниц". Если устранить проблему не удалось, снова установите флажок, чтобы страницы загружались быстрее.</translation>
+<translation id="6613594504749178791">Изменения вступят в силу при следующем входе в Chromium.</translation>
+<translation id="7861509383340276692">Откройте меню Chromium, нажмите "<ph name="SETTINGS_TITLE" />" &gt; "<ph name="ADVANCED_TITLE" />" и снимите флажок "<ph name="NO_PREFETCH_DESCRIPTION" />". Если устранить проблему не удалось, снова установите флажок, чтобы страницы загружались быстрее.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_sk.xtb b/chromium/components/strings/components_chromium_strings_sk.xtb
new file mode 100644
index 00000000000..e651068e65e
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_sk.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sk">
+<translation id="130631256467250065">Zmeny sa prejavia po ďalšom reštartovaní zariadenia.</translation>
+<translation id="4404275227760602850">Prejdite do Ponuky Chromium &gt; Nastavenia &gt; (Rozšírené) Ochrana osobných údajov
+ a zakážte možnosť Predbežne vyvolať zdroje stránky.
+ Ak týmto postupom daný problém nevyriešite, odporúčame vám túto možnosť
+ znova povoliť, aby ste získali lepšiu výkonnosť.</translation>
+<translation id="6613594504749178791">Zmeny sa prejavia pri nasledujúcom reštartovaní prehliadača Chromium.</translation>
+<translation id="7861509383340276692">Prejdite do
+ ponuky Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ a zrušte výber položky <ph name="NO_PREFETCH_DESCRIPTION" />.
+ Ak to problém nevyrieši, odporúčame túto možnosť vybrať,
+ aby ste získali lepšiu výkonnosť.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_sl.xtb b/chromium/components/strings/components_chromium_strings_sl.xtb
new file mode 100644
index 00000000000..dbc2ecb5a35
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_sl.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sl">
+<translation id="130631256467250065">Spremembe bodo uveljavljene pri naslednjem vnovičnem zagonu naprave.</translation>
+<translation id="4404275227760602850">Odprite Chromiumov meni &gt; Nastavitve &gt; (Dodatno) Zasebnost
+ in onemogočite »Vnaprej prenesi sredstva strani«.
+ Če s tem ne odpravite težave, priporočamo, da možnost znova
+ omogočite zaradi izboljšanega delovanja.</translation>
+<translation id="6613594504749178791">Spremembe bodo začele veljati ob naslednjem zagonu Chromiuma.</translation>
+<translation id="7861509383340276692">Odprite
+ meni Chromiuma &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ in počistite polje »<ph name="NO_PREFETCH_DESCRIPTION" />«.
+ Če s tem težave ne odpravite, priporočamo, da to možnost
+ zaradi izboljšanja delovanja znova izberete.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_sr.xtb b/chromium/components/strings/components_chromium_strings_sr.xtb
new file mode 100644
index 00000000000..fc71b6b5193
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_sr.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sr">
+<translation id="130631256467250065">Промене ће ступити на снагу када следећи пут поново покренете уређај.</translation>
+<translation id="4404275227760602850">Отворите Chromium мени &gt; Подешавања &gt; (Напредне опције) Приватност
+ и онемогућите „Припреми учитавање ресурса странице“.
+ Ако вам то не реши проблем, препоручујемо да поново омогућите
+ ову опцију ради бољих перформанси.</translation>
+<translation id="6613594504749178791">Промене ће ступити на снагу када следећи пут поново покренете Chromium.</translation>
+<translation id="7861509383340276692">Отворите
+ Chromium мени &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ и опозовите избор опције „<ph name="NO_PREFETCH_DESCRIPTION" />“.
+ Ако вам то не реши проблем, препоручујемо да поново изаберете
+ ову опцију ради бољих перформанси.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_sv.xtb b/chromium/components/strings/components_chromium_strings_sv.xtb
new file mode 100644
index 00000000000..8405a6e174b
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_sv.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sv">
+<translation id="130631256467250065">Dina ändringar börjar gälla nästa gång du startar om enheten.</translation>
+<translation id="4404275227760602850">Öppna Chromium-menyn &gt; Inställningar &gt; (Avancerat) Sekretess
+ och inaktivera Förhandshämta sidresurser.
+ Om det inte hjälper rekommenderar vi att du aktiverar alternativet
+ igen vilket ger bättre prestanda.</translation>
+<translation id="6613594504749178791">Ändringarna tillämpas nästa gång du startar om Chromium.</translation>
+<translation id="7861509383340276692">Öppna
+ Chromium-menyn &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ och avmarkera <ph name="NO_PREFETCH_DESCRIPTION" />.
+ Om det inte hjälper rekommenderar vi att du markerar det
+ här alternativet igen så att funktionaliteten förbättras.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_sw.xtb b/chromium/components/strings/components_chromium_strings_sw.xtb
new file mode 100644
index 00000000000..6b7e06ea692
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_sw.xtb
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sw">
+<translation id="130631256467250065">Mabadiliko yako yatatekelezwa utakapowasha upya tena kifaa chako.</translation>
+<translation id="4404275227760602850">Nenda kwenye menyu ya Chromium &gt; Mipangilio &gt; Faragha (Iliyoboreshwa)
+ na uzime "Leta mapema rasilimali za kurasa."
+ Ikiwa hili halitatui tatizo, tunapendekeza uwashe chaguo hili
+ tena kwa utendaji ulioimarishwa.</translation>
+<translation id="6613594504749178791">Mabadiliko yako yataanza kufanya kazi wakati ujao utakapozindua upya Chromium.</translation>
+<translation id="7861509383340276692">Nenda kwenye
+ menyu ya Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ <ph name="ADVANCED_TITLE" />na uondoe tiki kwenye "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Ikiwa hili halitatatua tatizo, tunapendekeza uchague tena chaguo hili kwa utendaji ulioboreshwa.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_ta.xtb b/chromium/components/strings/components_chromium_strings_ta.xtb
new file mode 100644
index 00000000000..b096c9b015d
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_ta.xtb
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ta">
+<translation id="130631256467250065">அடுத்த முறை உங்கள் சாதனத்தை மறுதொடக்கம் செய்யும்போது, மாற்றங்கள் செயல்பாட்டிற்கு வரும்.</translation>
+<translation id="4404275227760602850">Chromium மெனு &gt; அமைப்புகள் &gt; (மேம்பட்டது) தனியுரிமை என்பதற்குச் சென்று,
+ "பக்க மூலங்களைப் பெறு" என்பதை முடக்கவும்.
+ இது சிக்கலைத் தீர்க்கவில்லை எனில், மேம்பட்ட செயல்திறனுக்கு இந்த விருப்பத்தை
+ மீண்டும் இயக்கும்படி பரிந்துரைக்கிறோம்.</translation>
+<translation id="6613594504749178791">அடுத்த முறை நீங்கள் Chromium ஐ மீண்டும் தொடங்கும்போது உங்கள் மாற்றங்கள் செயல்படும்.</translation>
+<translation id="7861509383340276692">Chromium மெனு &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ என்பதற்குச் சென்று, "<ph name="NO_PREFETCH_DESCRIPTION" />" என்பதைத் தேர்வுநீக்கம் செய்யவும்.
+ இது சிக்கலைத் தீர்க்கவில்லை எனில், மேம்பட்ட செயல்திறனுக்கு இந்த விருப்பத்தை மீண்டும் தேர்ந்தெடுக்கும்படி பரிந்துரைக்கிறோம்.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_te.xtb b/chromium/components/strings/components_chromium_strings_te.xtb
new file mode 100644
index 00000000000..d6920aa61ee
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_te.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="te">
+<translation id="130631256467250065">మీ మార్పులు మీరు మీ పరికరాన్ని పునఃప్రారంభించే తదుపరిసారి ప్రభావవంతం అవుతాయి.</translation>
+<translation id="4404275227760602850">Chromium మెను &gt; సెట్టింగ్‌లు &gt; (అధునాతనం) గోప్యతకి వెళ్లి,
+ "పేజీ వనరులను ముందుగానే పొందండి" ఎంపిక నిలిపివేయండి.
+ దీని వలన సమస్య పరిష్కారం కాకపోతే, మెరుగైన పనితీరు కోసం ఈ ఎంపికను
+ మీరు మళ్లీ ప్రారంభించాలని మేము సిఫార్సు చేస్తున్నాము.</translation>
+<translation id="6613594504749178791">మీ మార్పులు మీరు Chromiumని మరుసటిసారి ప్రారంభించినప్పుడు ప్రభావాన్ని చూపుతాయి.</translation>
+<translation id="7861509383340276692">Chromium మెను &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />కి వెళ్లండి,
+ ఆపై "<ph name="NO_PREFETCH_DESCRIPTION" />" ఎంపికను తీసివేయండి.
+ దీని వల్ల సమస్య పరిష్కారం కాకుంటే, మెరుగైన పనితీరు కోసం మీరు
+ ఈ ఎంపికను మళ్లీ ఎంచుకోవాలని మేము సిఫార్సు చేస్తున్నాము.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_th.xtb b/chromium/components/strings/components_chromium_strings_th.xtb
new file mode 100644
index 00000000000..3491d97a861
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_th.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="th">
+<translation id="130631256467250065">การเปลี่ยนแปลงของคุณจะมีผลในครั้งถัดไปที่คุณรีสตาร์ทอุปกรณ์ของคุณ</translation>
+<translation id="4404275227760602850">ไปที่เมนู Chromium &gt; การตั้งค่า &gt; ความเป็นส่วนตัว (ขั้นสูง)
+ และปิดใช้ "ดึงทรัพยากรบนหน้าล่วงหน้า"
+ หากวิธีนี้ไม่ช่วยแก้ปัญหา เราขอแนะนำให้เปิดใช้ตัวเลือกนี้
+ อีกครั้งเพื่อให้ประสิทธิภาพการทำงานดียิ่งขึ้น</translation>
+<translation id="6613594504749178791">การเปลี่ยนแปลงของคุณจะมีผลในครั้งถัดไปที่คุณเปิด Chromium ขึ้นอีก</translation>
+<translation id="7861509383340276692">ไปที่
+ เมนู Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ และยกเลิกการเลือก "<ph name="NO_PREFETCH_DESCRIPTION" />"
+ หากวิธีนี้ไม่ช่วยแก้ปัญหา เราขอแนะนำให้เลือกตัวเลือกนี้
+ อีกครั้งเพื่อให้ประสิทธิภาพการทำงานดียิ่งขึ้น</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_tr.xtb b/chromium/components/strings/components_chromium_strings_tr.xtb
new file mode 100644
index 00000000000..a4f607fecab
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_tr.xtb
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="tr">
+<translation id="130631256467250065">Yaptığınız değişiklikler cihazı yeniden başlattığınızda etkinleşecektir.</translation>
+<translation id="4404275227760602850">Chromium menüsü &gt; Ayarlar &gt; (Gelişmiş) Gizlilik'e gidin
+ ve "Sayfa kaynaklarını ön getir"in işaretini kaldırın.
+ Bu işlem sorunu çözmezse performansın iyileşmesi için bu seçeneği tekrar 
+ etkinleştirmenizi öneririz.</translation>
+<translation id="6613594504749178791">Değişiklikleriniz, Chromium tekrar başlatıldığında geçerli olacak.</translation>
+<translation id="7861509383340276692">Chromium menüsü &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" /> öğesine gidin
+ ve "<ph name="NO_PREFETCH_DESCRIPTION" />" seçeneğinin işaretini kaldırın.
+ Bu işlem sorunu çözmezse performansın iyileşmesi için bu seçeneği tekrar işaretlemenizi öneririz.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_uk.xtb b/chromium/components/strings/components_chromium_strings_uk.xtb
new file mode 100644
index 00000000000..ccff1ad0f0f
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_uk.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="uk">
+<translation id="130631256467250065">Ваші зміни почнуть діяти під час наступного перезапуску пристрою.</translation>
+<translation id="4404275227760602850">Перейдіть у меню Chromium &gt; Налаштування &gt; (Розширені) Конфіденційність
+ і вимкніть опцію "Заздалегідь отримувати ресурси сторінки".
+ Якщо проблема не зникне, радимо знову ввімкнути цю опцію,
+ щоб покращити стабільність.</translation>
+<translation id="6613594504749178791">Ваші зміни почнуть діяти після наступного перезапуску Chromium.</translation>
+<translation id="7861509383340276692">Перейдіть у
+ меню Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ і зніміть прапорець біля опції "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Якщо проблема не зникне, радимо знову вибрати цю опцію,
+ щоб покращити стабільність.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_vi.xtb b/chromium/components/strings/components_chromium_strings_vi.xtb
new file mode 100644
index 00000000000..bfb0449746d
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_vi.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="vi">
+<translation id="130631256467250065">Thay đổi của bạn sẽ có hiệu lực vào lần tiếp theo bạn khởi động lại thiết bị của mình.</translation>
+<translation id="4404275227760602850">Chuyển đến menu Chromium &gt; Cài đặt &gt; Bảo mật (Nâng cao)
+ và tắt "Tìm nạp trước tài nguyên trang".
+ Nếu cách này không giải quyết được sự cố thì chúng tôi khuyên bạn nên bật lại tùy chọn này
+ để cải thiện hiệu suất.</translation>
+<translation id="6613594504749178791">Các thay đổi của bạn sẽ có hiệu lực vào lần tới khi bạn chạy lại Chromium.</translation>
+<translation id="7861509383340276692">Chuyển đến
+ menu Chromium &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ và bỏ chọn "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Nếu cách này không giải quyết được sự cố thì chúng tôi khuyên bạn nên chọn lại tùy chọn này
+ để cải thiện hiệu suất.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_zh-CN.xtb b/chromium/components/strings/components_chromium_strings_zh-CN.xtb
new file mode 100644
index 00000000000..98a444520fe
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_zh-CN.xtb
@@ -0,0 +1,9 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="zh-CN">
+<translation id="130631256467250065">您所做的更改会在下次重新启动设备时生效。</translation>
+<translation id="4404275227760602850">前往 Chromium 菜单 &gt;“设置”&gt;“隐私设置”(高级设置)部分,然后停用“预提取网页资源”。
+ 如果这无法解决该问题,我们建议您重新启用此选项,以便改善性能。</translation>
+<translation id="6613594504749178791">您所做的更改会在下次重新启动 Chromium 时生效。</translation>
+<translation id="7861509383340276692">前往 Chromium 菜单 &gt;“<ph name="SETTINGS_TITLE" />”&gt;“<ph name="ADVANCED_TITLE" />”部分,然后取消选中“<ph name="NO_PREFETCH_DESCRIPTION" />”。如果这无法解决该问题,我们建议您重新选中此选项,以便改善性能。</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_zh-TW.xtb b/chromium/components/strings/components_chromium_strings_zh-TW.xtb
new file mode 100644
index 00000000000..b1794de1952
--- /dev/null
+++ b/chromium/components/strings/components_chromium_strings_zh-TW.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="zh-TW">
+<translation id="130631256467250065">您的變更會在下次重新啟動裝置時生效。</translation>
+<translation id="4404275227760602850">前往 Chromium 選單 &gt; [設定] &gt; (進階) [隱私權]
+ 停用 [預先擷取網頁資源]。
+ 如果仍然無法解決問題,建議您重新啟用這個選項,
+ 讓 Chromium 的效能更優異。</translation>
+<translation id="6613594504749178791">您的變更將於下次重新啟動 Chromium 時生效。</translation>
+<translation id="7861509383340276692">前往
+ Chromium 選單 &gt;
+ [<ph name="SETTINGS_TITLE" />]
+ &gt;
+ [<ph name="ADVANCED_TITLE" />]
+ 然後取消勾選 [<ph name="NO_PREFETCH_DESCRIPTION" />]。
+ 如果仍然無法解決問題,建議您重新勾選這個選項
+ 以增進效能。</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_am.xtb b/chromium/components/strings/components_google_chrome_strings_am.xtb
new file mode 100644
index 00000000000..8f82b80c506
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_am.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="am">
+<translation id="130631256467250065">ለውጦችዎ መሣሪያዎን ዳግም በሚያስጀምሩበት ቀጣዩ ጊዜ ላይ ይተገበራሉ።</translation>
+<translation id="3140883423282498090">ለውጦችዎ Google Chrome ዳግም በሚያስጀምሩበት ቀጣዩ ጊዜ ላይ ይተገበራሉ።</translation>
+<translation id="5423788048750135178">ወደ Chrome ምናሌ &gt; ቅንብሮች &gt; (የላቁ) ግላዊነት ይሂዱ
+ እና «የገጽ ንብረቶችን ቅድሚያ አስመጣ»ን ያሰናክሉ።
+ ይሄ ችግሩን ካልፈታው ለተሻሻለ አፈጻጸም ይህን አማራጭ 
+ ዳግም ማንቃት እንመክራለን።</translation>
+<translation id="6341737370356890233">ወደ
+ የChrome ምናሌ &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ ይሂዱና «<ph name="NO_PREFETCH_DESCRIPTION" />»ን አይምረጡ።
+ ይሄ ችግሩን ካልፈታው ለተሻሻለ አፈጻጸም ይህን አማራጭ እንደገና መምረጥ እንመክራለን።</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_ar.xtb b/chromium/components/strings/components_google_chrome_strings_ar.xtb
new file mode 100644
index 00000000000..50d0d0fcd1d
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_ar.xtb
@@ -0,0 +1,21 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ar">
+<translation id="130631256467250065">تسري التغييرات في المرة التالية التي تعيد فيها تشغيل الجهاز.</translation>
+<translation id="3140883423282498090">‏ستسري التغييرات في المرة التالية التي تعيد فيها تشغيل Google Chrome.</translation>
+<translation id="5423788048750135178">‏انتقل إلى قائمة Chrome &gt; الإعدادات&gt; خصوصية (متقدمة)
+
+ وعطّل "موارد صفحة الجلب المسبق."
+
+ إذا لم يعمل هذا على حل المشكلة، نوصي بإعادة تمكين هذا الخيار
+
+ مرة أخرى من أجل أداء أفضل.</translation>
+<translation id="6341737370356890233">‏انتقل إلى
+ قائمة Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ وألغ تحديد <ph name="NO_PREFETCH_DESCRIPTION" />
+ إذا لم يعمل ذلك على حل المشكلة، نوصي بتحديد هذا الخيار
+ مرة من أجل أداء أفضل.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_bg.xtb b/chromium/components/strings/components_google_chrome_strings_bg.xtb
new file mode 100644
index 00000000000..2da7f160fd1
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_bg.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="bg">
+<translation id="130631256467250065">Промените ви ще влязат в сила следващия път, когато рестартирате устройството си.</translation>
+<translation id="3140883423282498090">Промените ви ще влязат в сила следващия път, когато стартирате отново Google Chrome.</translation>
+<translation id="5423788048750135178">Отворете менюто на Chrome &gt; „Настройки“ &gt; „Поверителност“ (под „Разширени“)
+и деактивирайте опцията за предварително зареждане на ресурсите на страниците.
+Ако това не реши проблема, препоръчваме ви да я активирате отново,
+за да подобрите ефективността.</translation>
+<translation id="6341737370356890233">Отворете
+менюто на Chrome &gt;
+„<ph name="SETTINGS_TITLE" />“
+&gt;
+„<ph name="ADVANCED_TITLE" />“
+и премахнете отметката от „<ph name="NO_PREFETCH_DESCRIPTION" />“.
+Ако това не реши проблема, препоръчваме ви да изберете отново тази опция,
+за да подобрите ефективността.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_bn.xtb b/chromium/components/strings/components_google_chrome_strings_bn.xtb
new file mode 100644
index 00000000000..0b6245a8e4f
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_bn.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="bn">
+<translation id="130631256467250065">পরের বার আপনি আপনার ডিভাইস পুনরারম্ভ করলে আপনার পরিবর্তনগুলি প্রভাবী হবে৷</translation>
+<translation id="3140883423282498090">আপনি পরবর্তী সময়ে যখন Google Chrome পুনরায় লঞ্চ করবেন আপনার পরিবর্তনগুলি কার্যকর হবে৷</translation>
+<translation id="5423788048750135178">Chromium মেনুতে যান &gt; সেটিংস &gt; (উন্নত) গোপনীয়তা
+ এবং "পৃষ্ঠার সংস্থান আনয়ন করা" অক্ষম করুন৷
+ যদি এটি সমস্যাটির সমাধান না করে, তাহলে উন্নত কার্য সম্পাদনার জন্য পুনরায়
+ এই বিকল্পটি নির্বাচন করা আমরা সুপারিশ করি৷</translation>
+<translation id="6341737370356890233">Chrome মেনুতে
+ যান &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ এবং অনির্বাচন করুন "<ph name="NO_PREFETCH_DESCRIPTION" />৷"
+ যদি এটি সমস্যাটির সমাধান না করে, তাহলে উন্নত কার্য সম্পাদনার জন্য পুনরায় এই বিকল্পটি নির্বাচন করা সুপারিশ আমরা করি৷</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_ca.xtb b/chromium/components/strings/components_google_chrome_strings_ca.xtb
new file mode 100644
index 00000000000..b63de50219f
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_ca.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ca">
+<translation id="130631256467250065">Els canvis es faran efectius la propera vegada que reinicieu el dispositiu.</translation>
+<translation id="3140883423282498090">Els canvis es faran efectius la propera vegada que reinicieu Google Chrome.</translation>
+<translation id="5423788048750135178">Aneu al menú de Chrome &gt; Configuració &gt; (Avançada) Privadesa
+ i desmarqueu "Baixa prèviament els recursos de la pàgina".
+ Si el problema no es resol, us recomanem que torneu a activar
+ aquesta opció per obtenir un millor rendiment.</translation>
+<translation id="6341737370356890233">Aneu al
+ menú de Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ i desmarqueu <ph name="NO_PREFETCH_DESCRIPTION" />.
+ Si això no resol el problema, us recomanem que torneu a seleccionar
+ aquesta opció per obtenir un rendiment millorat.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_cs.xtb b/chromium/components/strings/components_google_chrome_strings_cs.xtb
new file mode 100644
index 00000000000..3ce4b7ba1e6
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_cs.xtb
@@ -0,0 +1,8 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="cs">
+<translation id="130631256467250065">Změny se projeví po příštím restartu zařízení.</translation>
+<translation id="3140883423282498090">Změny se projeví po příštím restartu prohlížeče Google Chrome.</translation>
+<translation id="5423788048750135178">Přejděte do nabídky Chrome &gt; Nastavení &gt; (Rozšířené) Ochrana soukromí a zrušte výběr možnosti Předvídání síťových akcí. Pokud to však problém nevyřeší, doporučujeme vám tuto možnost znovu vybrat (za účelem zlepšení výkonu).</translation>
+<translation id="6341737370356890233">Přejděte do nabídky Chrome &gt; <ph name="SETTINGS_TITLE" /> &gt; <ph name="ADVANCED_TITLE" /> a zrušte výběr možnosti <ph name="NO_PREFETCH_DESCRIPTION" />. Pokud to však problém nevyřeší, doporučujeme vám tuto možnost znovu vybrat (za účelem zlepšení výkonu).</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_da.xtb b/chromium/components/strings/components_google_chrome_strings_da.xtb
new file mode 100644
index 00000000000..55a03a9f570
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_da.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="da">
+<translation id="130631256467250065">Dine ændringer træder i kraft, næste gang du genstarter din enhed.</translation>
+<translation id="3140883423282498090">Dine ændringer træder i kraft, næste gang du åbner Google Chrome.</translation>
+<translation id="5423788048750135178">Gå til Chrome-menuen &gt; Indstillinger &gt; (Avanceret) Privatliv,
+ og fjern markeringen af "Hent sideressourcer på forhånd".
+ Hvis det ikke løser problemet, bør du markere dette afkrydsningsfelt
+ igen for at forbedre effektiviteten.</translation>
+<translation id="6341737370356890233">Gå til
+ Chrome-menuen &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />,
+ og fjern markeringen af "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Hvis dette ikke løser problemet, bør du markere dette afkrydsningsfelt
+ igen for at forbedre effektiviteten.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_de.xtb b/chromium/components/strings/components_google_chrome_strings_de.xtb
new file mode 100644
index 00000000000..f0816503972
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_de.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="de">
+<translation id="130631256467250065">Ihre Änderungen werden beim nächsten Neustart wirksam.</translation>
+<translation id="3140883423282498090">Ihre Änderungen werden beim nächsten Neustart von Google Chrome wirksam.</translation>
+<translation id="5423788048750135178">Öffnen Sie das Chrome-Menü &gt; Einstellungen &gt; (Erweitert) Datenschutz
+ und deaktivieren Sie die Option "Vorabruf von Seitenressourcen".
+ Falls das Problem hierdurch nicht behoben wird, empfehlen wir,
+ diese Option für eine verbesserte Leistung wieder zu aktivieren.</translation>
+<translation id="6341737370356890233">Öffnen Sie
+ das Chrome-Menü &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ und deaktivieren Sie "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Falls das Problem nicht dadurch verursacht wurde, empfehlen wir,
+ diese Option für eine verbesserte Leistung wieder zu aktivieren.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_el.xtb b/chromium/components/strings/components_google_chrome_strings_el.xtb
new file mode 100644
index 00000000000..352c57bcbc1
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_el.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="el">
+<translation id="130631256467250065">Οι αλλαγές σας θα εφαρμοστούν την επόμενη φορά που θα επανεκκινήσετε τη συσκευή σας.</translation>
+<translation id="3140883423282498090">Οι αλλαγές που πραγματοποιήσατε θα ισχύσουν την επόμενη φορά που θα επανεκκινήσετε το Google Chrome.</translation>
+<translation id="5423788048750135178">Μεταβείτε στο μενού του Chrome &gt; Ρυθμίσεις &gt; (Για προχωρημένους) Απόρρητο
+ και απενεργοποιήστε την "Πρόωρη λήψη πόρων."
+ Αν δεν επιλυθεί το πρόβλημά σας με αυτόν τον τρόπο, σάς συνιστούμε να ενεργοποιήσετε ξανά αυτή την επιλογή
+ για βελτιωμένες επιδόσεις.</translation>
+<translation id="6341737370356890233">Μεταβείτε
+ στο μενού του Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ και καταργήστε την επιλογή "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Εάν με αυτόν τον τρόπο δεν επιλύεται το ζήτημά σας, συνιστούμε
+ να ενεργοποιήσετε ξανά αυτήν την επιλογή για βελτιωμένη απόδοση.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_en-GB.xtb b/chromium/components/strings/components_google_chrome_strings_en-GB.xtb
new file mode 100644
index 00000000000..b3fbcb28711
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_en-GB.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="en-GB">
+<translation id="130631256467250065">Your changes will take effect the next time that you restart your device.</translation>
+<translation id="3140883423282498090">Your changes will take effect the next time you relaunch Google Chrome.</translation>
+<translation id="5423788048750135178">Go to the Chrome menu &gt; Settings &gt; (Advanced) Privacy
+ and disable "Prefetch page resources".
+ If this does not resolve the issue, we recommend re-enabling this option
+ again for improved performance.</translation>
+<translation id="6341737370356890233">Go to
+ the Chrome menu &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ and deselect "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ If this does not resolve the issue, we recommend selecting this option
+ again for improved performance.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_es-419.xtb b/chromium/components/strings/components_google_chrome_strings_es-419.xtb
new file mode 100644
index 00000000000..5dea1828733
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_es-419.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="es-419">
+<translation id="130631256467250065">Los cambios se aplicarán la próxima vez que reinicies el dispositivo.</translation>
+<translation id="3140883423282498090">Los cambios se aplicarán la próxima vez que reinicies Google Chrome.</translation>
+<translation id="5423788048750135178">Ve al menú de Chrome &gt; Configuración &gt; (Avanzada) Privacidad
+ e inhabilita la opción para solicitar los recursos de la página previamente.
+ Si el problema persiste, vuelve a habilitar esta opción
+ para obtener un mejor rendimiento.</translation>
+<translation id="6341737370356890233">Ve
+ al menú de Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ y anula la selección de "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Si esto no resuelve el problema, vuelve a habilitar esta opción
+ para obtener un mejor desempeño.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_es.xtb b/chromium/components/strings/components_google_chrome_strings_es.xtb
new file mode 100644
index 00000000000..68593187965
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_es.xtb
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="es">
+<translation id="130631256467250065">Los cambios se aplicarán la próxima vez que reinicies el dispositivo.</translation>
+<translation id="3140883423282498090">Los cambios se aplicarán la próxima vez que reinicies Google Chrome.</translation>
+<translation id="5423788048750135178">Accede al menú de Chrome, selecciona Ajustes, haz clic en Privacidad (Avanzados) e inhabilita la opción de cargar previamente recursos de página. Si esto no soluciona el problema, te recomendamos que vuelvas a habilitar esta opción para mejorar el rendimiento.</translation>
+<translation id="6341737370356890233">Accede al
+ menú de Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ y desactiva la opción "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Si esto no soluciona el problema, te recomendamos que vuelvas a seleccionar esta opción
+ para conseguir un mejor rendimiento.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_et.xtb b/chromium/components/strings/components_google_chrome_strings_et.xtb
new file mode 100644
index 00000000000..affea0031a5
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_et.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="et">
+<translation id="130631256467250065">Muudatused jõustuvad järgmine kord, kui seadme taaskäivitate.</translation>
+<translation id="3140883423282498090">Teie muudatused jõustuvad järgmine kord, kui avate Google Chrome'i.</translation>
+<translation id="5423788048750135178">Avage Chrome'i menüü &gt; Seaded &gt; (Täpsem) Privaatsus
+ ja keelake valik „Lehe ressursside eellaadimine”.
+ Kui see probleemi ei lahenda, soovitame selle valiku toimivuse
+ parandamiseks uuesti lubada.</translation>
+<translation id="6341737370356890233">Avage
+ Chrome'i menüü &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ ja tühistage valik „<ph name="NO_PREFETCH_DESCRIPTION" />”.
+ Kui see probleemi ei lahenda, soovitame toimivuse parandamiseks
+ selle valiku uuesti teha.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_fa.xtb b/chromium/components/strings/components_google_chrome_strings_fa.xtb
new file mode 100644
index 00000000000..0510806d0c2
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_fa.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fa">
+<translation id="130631256467250065">تغییرات بار بعد که دستگاه راه‌اندازی می‌شود اعمال می‌شوند.</translation>
+<translation id="3140883423282498090">‏دفعه بعد که Google Chrome را مجدداً راه‌اندازی می‌کنید، این تغییرات اعمال می‌شوند.</translation>
+<translation id="5423788048750135178">‏به منوی Chrome &gt; تنظیمات &gt; (پیشرفته) حریم خصوصی
+ بروید و «واکشی منابع صفحه» را غیرفعال کنید.
+ درصورتی‌که با این کار مشکل حل نشد، توصیه می‌کنیم برای عملکرد بهبودیافته،
+  این گزینه را دوباره فعال کنید.</translation>
+<translation id="6341737370356890233">‏به
+ منوی Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ بروید و علامت «<ph name="NO_PREFETCH_DESCRIPTION" />» را بردارید.
+ درصورتی‌که با این کار مشکل حل نشد، توصیه می‌کنیم برای عملکرد پیشرفته،
+   این گزینه را دوباره انتخاب کنید.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_fi.xtb b/chromium/components/strings/components_google_chrome_strings_fi.xtb
new file mode 100644
index 00000000000..addfa8b1b98
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_fi.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fi">
+<translation id="130631256467250065">Muutokset tulevat voimaan, kun käynnistät laitteen seuraavan kerran.</translation>
+<translation id="3140883423282498090">Muutokset tulevat voimaan, kun käynnistät Google Chromen seuraavan kerran.</translation>
+<translation id="5423788048750135178">Avaa Chrome-valikko &gt; Asetukset &gt; Tietosuoja (Lisäasetukset)
+ ja poista valinta kohdasta Hae valmiiksi sivun resurssit.
+ Jos ongelma ei ratkea, valitse tämä vaihtoehto uudelleen suorituskyvyn
+ parantamiseksi.</translation>
+<translation id="6341737370356890233">Avaa
+ Chrome-valikko &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ ja poista valinta kohdasta <ph name="NO_PREFETCH_DESCRIPTION" />.
+ Jos ongelma ei ratkea, valitse tämä vaihtoehto
+ uudelleen suorituskyvyn parantamiseksi.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_fil.xtb b/chromium/components/strings/components_google_chrome_strings_fil.xtb
new file mode 100644
index 00000000000..24b890d7af7
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_fil.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fil">
+<translation id="130631256467250065">Magkakabisa ang iyong mga pagbabago sa susunod na i-restart ang iyong device.</translation>
+<translation id="3140883423282498090">Magkakaroon ng bisa ang iyong mga pagbabago sa susunod na pagkakataong muli mong ilunsad ang Google Chrome.</translation>
+<translation id="5423788048750135178">Pumunta sa menu ng Chrome &gt; Mga Setting &gt; (Advanced) Privacy
+ at i-disable ang "I-prefetch ang mga mapagkukunan ng page."
+ Kung hindi nito malutas ang isyu, inirerekomenda naming muling
+ i-enable ang opsyong ito para sa mas mahusay na pagganap.</translation>
+<translation id="6341737370356890233">Pumunta
+ sa menu ng Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ at alisin sa pagkakapili ang "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Kung hindi nito malulutas ang isyu, inirerekomenda naming piliing muli ang opsyong ito
+ para sa pinahusay na pagganap.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_fr.xtb b/chromium/components/strings/components_google_chrome_strings_fr.xtb
new file mode 100644
index 00000000000..60f46e34549
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_fr.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fr">
+<translation id="130631256467250065">Vos modifications seront prises en compte au prochain démarrage de l'appareil.</translation>
+<translation id="3140883423282498090">Vos modifications seront prises en compte au prochain redémarrage de Google Chrome.</translation>
+<translation id="5423788048750135178">Accédez au menu Chrome &gt; Paramètres &gt; (Avancés) Confidentialité,
+ puis désactivez "Prélire les ressources de pages".
+ Si le problème persiste, nous vous conseillons de réactiver cette option
+ pour des performances optimales.</translation>
+<translation id="6341737370356890233">Accédez au
+ menu Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />,
+ puis décochez l'option "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Si le problème persiste, nous vous conseillons de réactiver
+ cette option pour des performances optimales.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_gu.xtb b/chromium/components/strings/components_google_chrome_strings_gu.xtb
new file mode 100644
index 00000000000..fe5a9607f6a
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_gu.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="gu">
+<translation id="130631256467250065">તમારા ફેરફારો તમે આગલી વખતે તમારા ઉપકરણને ફરી પ્રારંભ કરશો ત્યારે પ્રભાવમાં આવશે.</translation>
+<translation id="3140883423282498090">તમે આગલી વખત Google Chrome ને ફરીથી શરૂ કરશો ત્યારે તમારા ફેરફારો પ્રભાવી થશે.</translation>
+<translation id="5423788048750135178">Chrome મેનૂ &gt; સેટિંગ્સ &gt; (વિગતવાર) ગોપનીયતા પર જાઓ
+ અને "પૃષ્ઠ સંસાધનોનું પૂર્વ આનયન કરો" ને અક્ષમ કરો.
+ જો આનાથી સમસ્યા ઉકેલાતી નથી, તો અમે સુધારેલ પ્રદર્શન માટે ફરીથી આ વિકલ્પને પસંદ કરવાની
+ ભલામણ કરીએ છીએ.</translation>
+<translation id="6341737370356890233">Chrome મેનૂ &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ પર જાઓ અને "<ph name="NO_PREFETCH_DESCRIPTION" />" પસંદગીને હટાવો.
+ જો આનાથી સમસ્યા ઉકેલાતી નથી, તો અમે સુધારેલ પ્રદર્શન માટે ફરીથી આ વિકલ્પને પસંદ કરવાની
+ ભલામણ કરીએ છીએ.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_hi.xtb b/chromium/components/strings/components_google_chrome_strings_hi.xtb
new file mode 100644
index 00000000000..ce948926b8c
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_hi.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hi">
+<translation id="130631256467250065">अगली बार अपना डिवाइस पुन: प्रारंभ करने पर आपके परिवर्तन प्रभावी हो जाएंगे.</translation>
+<translation id="3140883423282498090">आपके द्वारा अगली बार Google Chrome को पुन: लॉन्‍च करने पर आपके परिवर्तन प्रभावी हो जाएंगे.</translation>
+<translation id="5423788048750135178">Chrome मेनू &gt; सेटिंग &gt; (उन्‍नत) गोपनीयता पर जाएं
+ और "पृष्‍ठ संसाधनों को प्रीफ़ेच करें" को अक्षम करें.
+ यदि इससे समस्‍या हल नहीं होती, तो बेहतर प्रदर्शन के लिए हम इस विकल्‍प को पुन:
+ सक्षम करने की अनुशंसा करते हैं.</translation>
+<translation id="6341737370356890233">Chrome
+ मेनू &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ पर जाएं और "<ph name="NO_PREFETCH_DESCRIPTION" />" का चयन हटाएं
+ यदि इससे समस्या का समाधान नहीं होता, तो बेहतर प्रदर्शन के लिए हम इस विकल्‍प को पुन: चुनने
+ की अनुशंसा करते हैं.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_hr.xtb b/chromium/components/strings/components_google_chrome_strings_hr.xtb
new file mode 100644
index 00000000000..7c05ca56df9
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_hr.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hr">
+<translation id="130631256467250065">Promjene će početi vrijediti sljedeći put kad ponovo pokrenete uređaj.</translation>
+<translation id="3140883423282498090">Vaše izmjene stupit će na snagu sljedeći put kada se ponovo pokrene Google Chrome.</translation>
+<translation id="5423788048750135178">Otvorite izbornik Chromea &gt; Postavke &gt; (Napredno) Privatnost
+ i onemogućite "Unaprijed dohvati resurse stranice".
+ Ako se time ne riješi poteškoća, preporučujemo da ponovo omogućite tu opciju
+ radi bolje izvedbe.</translation>
+<translation id="6341737370356890233">Otvorite
+ izbornik Chromea &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ pa poništite odabir stavke "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Ako se time ne riješi poteškoća, preporučujemo da ponovo odaberete tu opciju radi bolje izvedbe.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_hu.xtb b/chromium/components/strings/components_google_chrome_strings_hu.xtb
new file mode 100644
index 00000000000..c5b1f42de26
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_hu.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hu">
+<translation id="130631256467250065">A módosítások az eszköz következő újraindításakor lépnek életbe.</translation>
+<translation id="3140883423282498090">A módosítások a következő alkalommal lépnek életbe, amikor újraindítja a Google Chrome-ot.</translation>
+<translation id="5423788048750135178">Nyissa meg a Chrome-menü &gt; Beállítások &gt; (Speciális) Adatvédelem menüelemet,
+ és tiltsa le az „Oldalforrások előzetes lehívása” beállítást.
+ Ha ettől nem szűnik meg a probléma, javasoljuk, hogy engedélyezze újra ezt a lehetőséget
+ a jobb teljesítmény érdekében.</translation>
+<translation id="6341737370356890233">Lépjen ide:
+ Chrome menü &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />,
+ és törölje a jelet a(z) „<ph name="NO_PREFETCH_DESCRIPTION" />” jelölőnégyzetből.
+ Ha ettől nem szűnik meg a probléma, javasoljuk, hogy jelölje be ismét
+ ezt a lehetőséget a jobb teljesítmény érdekében.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_id.xtb b/chromium/components/strings/components_google_chrome_strings_id.xtb
new file mode 100644
index 00000000000..a3e0c9fd584
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_id.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="id">
+<translation id="130631256467250065">Perubahan Anda akan diterapkan pada saat Anda nanti menyalakan ulang perangkat.</translation>
+<translation id="3140883423282498090">Perubahan Anda akan berlaku pada peluncuran ulang Google Chrome selanjutnya.</translation>
+<translation id="5423788048750135178">Buka menu Chrome &gt; Setelan &gt; (Lanjutan) Privasi
+ dan nonaktifkan "Ambil sumber daya laman lebih dahulu".
+ Jika hal ini tidak menyelesaikan masalah, sebaiknya aktifkan opsi ini
+ lagi untuk kinerja yang ditingkatkan.</translation>
+<translation id="6341737370356890233">Buka
+ menu Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ dan batalkan pilihan "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Jika hal ini tidak menyelesaikan masalah, sebaiknya pilih lagi opsi ini
+ untuk meningkatkan kinerja.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_it.xtb b/chromium/components/strings/components_google_chrome_strings_it.xtb
new file mode 100644
index 00000000000..7d3dee6aa8e
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_it.xtb
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="it">
+<translation id="130631256467250065">Le modifiche verranno applicate al successivo riavvio del dispositivo.</translation>
+<translation id="3140883423282498090">Le modifiche verranno applicate al prossimo riavvio di Google Chrome.</translation>
+<translation id="5423788048750135178">Seleziona il menu Chrome &gt; Impostazioni &gt; (Avanzate) Privacy e disattiva l'opzione "Precarica risorse delle pagine".
+Se il problema non si risolve, dovresti riattivare questa opzione per ottenere prestazioni migliori.</translation>
+<translation id="6341737370356890233">Seleziona il menu Chrome &gt; <ph name="SETTINGS_TITLE" /> &gt; <ph name="ADVANCED_TITLE" /> e deseleziona "<ph name="NO_PREFETCH_DESCRIPTION" />".
+Se il problema non si risolve, dovresti riselezionare questa opzione per ottenere prestazioni migliori.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_iw.xtb b/chromium/components/strings/components_google_chrome_strings_iw.xtb
new file mode 100644
index 00000000000..6f144375b5e
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_iw.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="iw">
+<translation id="130631256467250065">השינויים ייכנסו לתוקף בפעם הבאה שתפעיל מחדש את המכשיר.</translation>
+<translation id="3140883423282498090">‏השינויים ייכנסו לתוקף בפעם הבאה שתשיק מחדש את Google Chrome.</translation>
+<translation id="5423788048750135178">‏עבור אל תפריט Chrome &gt; הגדרות &gt; (מתקדם) פרטיות
+ והשבת את 'בצע אחזור מוקדם למשאבי דף'.
+ אם פעולה זו אינה פותרת את הבעיה, מומלץ להפעיל שוב את האפשרות הזו
+ כדי לשפר את הביצועים.</translation>
+<translation id="6341737370356890233">‏עבור אל
+ תפריט Chrome‏ &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ ובטל את הבחירה באפשרות '<ph name="NO_PREFETCH_DESCRIPTION" />'.
+ אם פעולה זו אינה פותרת את הבעיה, מומלץ לבחור שוב באפשרות זו
+ לקבלת ביצועים משופרים.</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
new file mode 100644
index 00000000000..2cba5b411c8
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_ja.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ja">
+<translation id="130631256467250065">変更内容は、次回の端末の起動時に反映されます。</translation>
+<translation id="3140883423282498090">変更内容は次に Google Chrome を再起動したときに有効になります。</translation>
+<translation id="5423788048750135178">Chrome メニュー &gt; [設定] &gt; [(詳細)プライバシー] の順に移動して、
+ [ページリソースのプリフェッチ] を無効にします。
+ 上記を行っても問題が解決しない場合は、パフォーマンス向上のため
+ このオプションを再び有効にすることをおすすめします。</translation>
+<translation id="6341737370356890233">Chrome メニュー &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ の順に移動して、[<ph name="NO_PREFETCH_DESCRIPTION" />] をオフにします。
+ 上記を行っても問題が解決しない場合は、パフォーマンス向上のため
+ このオプションを再びオンにすることをおすすめします。</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_kn.xtb b/chromium/components/strings/components_google_chrome_strings_kn.xtb
new file mode 100644
index 00000000000..0227fdf639e
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_kn.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="kn">
+<translation id="130631256467250065">ನಿಮ್ಮ ಸಾಧನವನ್ನು ನೀವು ಮುಂದಿನ ಬಾರಿ ಮರುಪ್ರಾರಂಭಿಸಿದಾಗ ನಿಮ್ಮ ಬದಲಾವಣೆಗಳು ಕಾರ್ಯಗತಗೊಳ್ಳುತ್ತವೆ.</translation>
+<translation id="3140883423282498090">ನೀವು ಮುಂದಿನ ಬಾರಿ Google Chrome ಮರುಪ್ರಾರಂಭಿಸಿದಾಗ ನಿಮ್ಮ ಬದಲಾವಣೆಗಳು ಕಾರ್ಯಗತಗೊಳ್ಳುತ್ತವೆ.</translation>
+<translation id="5423788048750135178">Chrome ಮೆನು &gt; ಸೆಟ್ಟಿಂಗ್‌ಗಳು &gt; (ಸುಧಾರಿತ) ಗೌಪ್ಯತೆಗೆ ಹೋಗಿ
+ ಮತ್ತು "ಪುಟ ಸಂಪನ್ಮೂಲಗಳನ್ನು ಪೂರ್ವಪಡೆಯುವಿಕೆ" ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ
+ ಒಂದು ವೇಳೆ ಇದು ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸದಿದ್ದರೆ, ಸುಧಾರಿತ ಕಾರ್ಯಾಚರಣೆಗಾಗಿ ಮತ್ತೊಮ್ಮೆ
+ ಈ ಆಯ್ಕೆಯನ್ನು ಮರುಸಕ್ರಿಯಗೊಳಿಸುವಂತೆ ನಾವು ಶಿಫಾರಸು ಮಾಡುತ್ತೇವೆ.</translation>
+<translation id="6341737370356890233">ಇದಕ್ಕೆ ಹೋಗಿ
+ Chrome ಮೆನು &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ ಮತ್ತು "<ph name="NO_PREFETCH_DESCRIPTION" />" ಆಯ್ಕೆ ರದ್ದುಪಡಿಸಿ.
+ ಒಂದು ವೇಳೆ ಇದು ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸದಿದ್ದರೆ, ಸುಧಾರಿತ ಕಾರ್ಯಾಚರಣೆಗೆ ಮತ್ತೊಮ್ಮೆ
+ ಈ ಆಯ್ಕೆಯನ್ನು ಆಯ್ಕೆ ಮಾಡುವಂತೆ ನಾವು ಶಿಫಾರಸು ಮಾಡುತ್ತೇವೆ.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_ko.xtb b/chromium/components/strings/components_google_chrome_strings_ko.xtb
new file mode 100644
index 00000000000..a36bd2d88ba
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_ko.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ko">
+<translation id="130631256467250065">기기를 다시 시작할 때 변경사항이 적용됩니다.</translation>
+<translation id="3140883423282498090">Chrome을 다시 시작하면 변경사항이 적용됩니다.</translation>
+<translation id="5423788048750135178">Chrome 메뉴 &gt; 설정 &gt; (고급)개인정보로
+ 이동하여 '페이지 리소스 프리패치'를 사용 중지합니다.
+ 그래도 문제가 해결되지 않으면 이 옵션을 다시 사용 설정하여
+ 성능을 개선해 보시기 바랍니다.</translation>
+<translation id="6341737370356890233">Chrome 메뉴 &gt;
+
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ (으)로 이동하고 '<ph name="NO_PREFETCH_DESCRIPTION" />'을(를) 선택 취소합니다.
+ 그래도 문제가 해결되지 않으면 이 옵션을 다시 선택하여
+ 성능을 개선해 보시기 바랍니다.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_lt.xtb b/chromium/components/strings/components_google_chrome_strings_lt.xtb
new file mode 100644
index 00000000000..38aae9c798d
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_lt.xtb
@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="lt">
+<translation id="130631256467250065">Pakeitimai įsigalios kitą kartą iš naujo paleidus įrenginį.</translation>
+<translation id="3140883423282498090">Pakeitimai įsigalios kitą kartą iš naujo paleidus „Google Chrome“.</translation>
+<translation id="5423788048750135178">Eikite į „Chrome“ meniu &gt; Nustatymai &gt; (Išplėstiniai) Privatumas
+ ir išjunkite parinktį „Iš anksto iškviesti puslapio išteklius“.
+ Jei tai atlikus problema išlieka, rekomenduojame iš naujo įgalinti šią parinktį,
+ kad pagerėtų našumas.</translation>
+<translation id="6341737370356890233">Eikite į
+
+ „Chrome“ meniu &gt;
+ „<ph name="SETTINGS_TITLE" />“
+ &gt;
+ „<ph name="ADVANCED_TITLE" />“
+ ir panaikinkite „<ph name="NO_PREFETCH_DESCRIPTION" />“ pasirinkimą.
+ Jei tai atlikus problema išlieka, rekomenduojame vėl pasirinkti šią parinktį,
+ kad pagerėtų našumas.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_lv.xtb b/chromium/components/strings/components_google_chrome_strings_lv.xtb
new file mode 100644
index 00000000000..0569f9fc03d
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_lv.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="lv">
+<translation id="130631256467250065">Izmaiņas stāsies spēkā nākamajā reizē, kad restartēsiet ierīci.</translation>
+<translation id="3140883423282498090">Jūsu izmaiņas stāsies spēkā nākamajā reizē, kad atkārtoti palaidīsiet pārlūku Google Chrome.</translation>
+<translation id="5423788048750135178">Atveriet Chrome izvēlni &gt; Iestatījumi &gt; (Papildu) Konfidencialitāte
+ un atspējojiet opciju “Sākotnēji iegūt lapu resursus”.
+ Ja problēma netiek novērsta, ieteicams atkārtoti iespējot šo opciju,
+ lai uzlabotu veiktspēju.</translation>
+<translation id="6341737370356890233">Atveriet
+ Chrome izvēlni &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ un noņemiet atzīmi no izvēles rūtiņas “<ph name="NO_PREFETCH_DESCRIPTION" />”.
+ Ja problēmu neizdodas novērst, ieteicams atkal atlasīt šo opciju,
+ lai uzlabotu veiktspēju.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_ml.xtb b/chromium/components/strings/components_google_chrome_strings_ml.xtb
new file mode 100644
index 00000000000..ccfecd00293
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_ml.xtb
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ml">
+<translation id="130631256467250065">നിങ്ങൾ അടുത്ത തവണ ഉപകരണം പുനരാരംഭിക്കുമ്പോൾ മാറ്റങ്ങൾ പ്രാബല്യത്തിൽ വരും.</translation>
+<translation id="3140883423282498090">നിങ്ങളുടെ മാറ്റങ്ങൾ അടുത്ത തവണ Google Chrome പുനഃസമാരംഭിക്കുമ്പോൾ പ്രാബല്യത്തിൽ വരും.</translation>
+<translation id="5423788048750135178">Chrome മെനു &gt; ക്രമീകരണം &gt; (വിപുലീകരിച്ചത്) സ്വകാര്യത എന്നതിലേക്ക് പോയി
+ ''പ്രീഫെച്ച് പേജ് ഉറവിടങ്ങൾ''പ്രവർത്തനരഹിതമാക്കുക.
+ ഇത് പ്രശ്‌നം പരിഹരിച്ചില്ലെങ്കിൽ, മെച്ചപ്പെട്ട പ്രവർത്തനത്തിനായി ഈ
+ ഓപ്‌ഷൻ വീണ്ടും പ്രവർത്തനക്ഷമമാക്കാൻ ഞങ്ങൾ ശുപാർശചെയ്യുന്നു.</translation>
+<translation id="6341737370356890233">Chrome മെനു &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" /> എന്നതിലേക്ക് പോയി
+ "<ph name="NO_PREFETCH_DESCRIPTION" />" തിരഞ്ഞെടുത്തത് മാറ്റുക.
+ ഇത് പ്രശ്‌നം പരിഹരിക്കുന്നില്ലെങ്കിൽ, മെച്ചപ്പെട്ട പ്രകടനത്തിനായി ഈ ഓപ്‌ഷൻ വീണ്ടും തിരഞ്ഞെടുക്കുന്നതിനായി ഞങ്ങൾ ശുപാർശചെയ്യുന്നു.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_mr.xtb b/chromium/components/strings/components_google_chrome_strings_mr.xtb
new file mode 100644
index 00000000000..bb6d8211f0a
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_mr.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="mr">
+<translation id="130631256467250065">आपण आपल्या डिव्हाइसचा पुढील वेळी पुनरारंभ कराल तेव्हा आपले बदल प्रभावी होतील.</translation>
+<translation id="3140883423282498090">पुढील वेळी आपण Google Chrome पुन्हा लाँच केल्यानंतर आपले बदल प्रभावी होतील.</translation>
+<translation id="5423788048750135178">Chrome मेनू &gt; सेटिंग्ज &gt; (प्रगत) गोपनीयता वर जा
+ आणि "पृष्ठ संसाधने अगोदर आणा" अक्षम करा.
+ यामुळे समस्येचे निराकरण होत नसल्यास, सुधारित कार्यप्रदर्शनासाठी हा पुन्हा या
+ पर्यायास पुन्हा-सक्षम करण्याची आम्ही शिफारस करतो.</translation>
+<translation id="6341737370356890233">Chrome मेनू &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ वर जा आणि "<ph name="NO_PREFETCH_DESCRIPTION" />" ची निवड रद्द करा.
+ हे समस्‍येचे निराकरण करीत नसल्‍यास, आम्‍ही सुधारित सुधारित कार्यप्रदर्शनासाठी पुन्हा
+ हा पर्याय निवडण्याची शिफारस करतो.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_ms.xtb b/chromium/components/strings/components_google_chrome_strings_ms.xtb
new file mode 100644
index 00000000000..b3d1d5aa84b
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_ms.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ms">
+<translation id="130631256467250065">Perubahan anda akan dilaksanakan apabila anda memulakan semula peranti anda pada masa akan datang.</translation>
+<translation id="3140883423282498090">Perubahan anda akan berkuat kuasa apabila anda melancarkan semula Google Chrome pada masa hadapan.</translation>
+<translation id="5423788048750135178">Pergi ke menu Chrome &gt; Tetapan &gt; (Lanjutan) Privasi
+ dan lumpuhkan "Praambil sumber halaman."
+ Jika tindakan ini tidak menyelesaikan isu ini, kami cadangkan agar mendayakan semula pilihan ini
+ sekali lagi untuk prestasi yang lebih baik.</translation>
+<translation id="6341737370356890233">Pergi ke
+ menu Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ dan nyahpilih "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Jika tindakan ini tidak menyelesaikan isu ini, kami cadangkan agar memilih pilihan ini
+ sekali lagi untuk prestasi yang dipertingkatkan.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_nl.xtb b/chromium/components/strings/components_google_chrome_strings_nl.xtb
new file mode 100644
index 00000000000..05b84ab7259
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_nl.xtb
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="nl">
+<translation id="130631256467250065">Je wijzigingen worden doorgevoerd wanneer je het apparaat opnieuw opstart.</translation>
+<translation id="3140883423282498090">Je wijzigingen worden toegepast als je Google Chrome opnieuw start.</translation>
+<translation id="5423788048750135178">Ga naar het Chrome-menu &gt; Instellingen &gt; (Geavanceerd) Privacy en schakel 'Paginabronnen prefetchen' uit. Als het probleem hiermee niet wordt opgelost, raden we je aan deze optie weer in te schakelen voor verbeterde prestaties.</translation>
+<translation id="6341737370356890233">Ga naar
+ het Chrome-menu &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ en verwijder het vinkje bij '<ph name="NO_PREFETCH_DESCRIPTION" />'.
+ Als het probleem aanhoudt, adviseren we deze optie weer aan te vinken
+ voor betere prestaties.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_no.xtb b/chromium/components/strings/components_google_chrome_strings_no.xtb
new file mode 100644
index 00000000000..d9980f62fe4
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_no.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="no">
+<translation id="130631256467250065">Endringene trer i kraft neste gang du starter enheten på nytt.</translation>
+<translation id="3140883423282498090">Endringene dine trer i kraft neste gang du starter Google Chrome.</translation>
+<translation id="5423788048750135178">Gå til Chrome-menyen &gt; Innstillinger &gt; (Avansert) Personvern,
+ og slå av alternativet for henting av sideressurser på forhånd.
+ Hvis ikke dette løser problemet, bør du slå på dette alternativet
+ igjen for å bedre ytelsen.</translation>
+<translation id="6341737370356890233">Gå til
+ Chrome-menyen &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ og fjern avmerkingen for «<ph name="NO_PREFETCH_DESCRIPTION" />».
+ Hvis dette ikke løser problemet, bør du velge dette alternativet
+ på nytt for bedre ytelse.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_pl.xtb b/chromium/components/strings/components_google_chrome_strings_pl.xtb
new file mode 100644
index 00000000000..8072ccb9dee
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_pl.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pl">
+<translation id="130631256467250065">Zmiany zostaną zastosowane przy następnym uruchomieniu urządzenia.</translation>
+<translation id="3140883423282498090">Zmiany zaczną obowiązywać po ponownym uruchomieniu Google Chrome.</translation>
+<translation id="5423788048750135178">Wybierz kolejno menu Chrome &gt; Ustawienia &gt; (Zaawansowane) Prywatność
+ i wyłącz „Wstępnie pobieraj zasoby strony”.
+ Jeśli to nie rozwiąże problemu, zalecamy ponowne włączenie tej opcji,
+ by poprawić wydajność.</translation>
+<translation id="6341737370356890233">Wybierz
+ menu Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ i odznacz „<ph name="NO_PREFETCH_DESCRIPTION" />”.
+ Jeśli nie rozwiąże to problemu, zalecamy ponowne wybranie tej opcji,
+ by poprawić wydajność.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_pt-BR.xtb b/chromium/components/strings/components_google_chrome_strings_pt-BR.xtb
new file mode 100644
index 00000000000..8642dcefc85
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_pt-BR.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pt-BR">
+<translation id="130631256467250065">As alterações entrarão em vigor na próxima vez que você reiniciar o dispositivo.</translation>
+<translation id="3140883423282498090">Suas alterações terão efeito na próxima vez que você reiniciar o Google Chrome.</translation>
+<translation id="5423788048750135178">Vá até o menu do Chrome &gt; Configurações &gt; (Avançadas) Privacidade
+ e desative "Recursos de página de pré-chamada".
+ Se isso não resolver o problema, recomendamos que você reative essa opção
+ novamente para melhorar o desempenho.</translation>
+<translation id="6341737370356890233">Vá para
+ o menu do Google Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ e desmarque "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Se isso não resolver o problema, recomendamos que você selecione esta opção
+ novamente para melhorar o desempenho.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_pt-PT.xtb b/chromium/components/strings/components_google_chrome_strings_pt-PT.xtb
new file mode 100644
index 00000000000..acddd5936b8
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_pt-PT.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pt-PT">
+<translation id="130631256467250065">As alterações terão efeito da próxima vez que reiniciar o dispositivo.</translation>
+<translation id="3140883423282498090">As alterações terão efeito da próxima vez que voltar a iniciar o Google Chrome.</translation>
+<translation id="5423788048750135178">Aceda ao menu do Chrome &gt; Definições &gt; Privacidade (avançada)
+ e desative "Registar previamente os recursos da página".
+ Se esta ação não resolver o problema, recomendamos que reative esta opção
+ novamente para melhorar o desempenho.</translation>
+<translation id="6341737370356890233">Aceda ao
+ menu Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ e desmarque "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Se isso não resolver o problema, recomendamos que selecione esta opção
+ novamente para obter um desempenho melhorado.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_ro.xtb b/chromium/components/strings/components_google_chrome_strings_ro.xtb
new file mode 100644
index 00000000000..19109c61a0c
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_ro.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ro">
+<translation id="130631256467250065">Modificările dvs. se vor aplica următoarea dată când reporniți dispozitivul.</translation>
+<translation id="3140883423282498090">Modificările se vor aplica următoarea dată când relansați Google Chrome.</translation>
+<translation id="5423788048750135178">Accesează meniul Chrome &gt; Setări &gt; (Avansate) Confidențialitate
+ și dezactivează „Preia în avans resursele paginii”.
+ Dacă această acțiune nu rezolvă problema, îți recomandăm să reactivezi
+ această opțiune pentru îmbunătățirea performanței.</translation>
+<translation id="6341737370356890233">Accesează
+ meniul Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ și debifează „<ph name="NO_PREFETCH_DESCRIPTION" />”.
+ Dacă această acțiune nu rezolvă problema, îți recomandăm să selectezi din nou
+ această opțiune pentru performanță îmbunătățită.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_ru.xtb b/chromium/components/strings/components_google_chrome_strings_ru.xtb
new file mode 100644
index 00000000000..a5d74502fba
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_ru.xtb
@@ -0,0 +1,8 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ru">
+<translation id="130631256467250065">Изменения вступят в силу после перезагрузки устройства.</translation>
+<translation id="3140883423282498090">Внесенные изменения станут активны после перезапуска Google Chrome.</translation>
+<translation id="5423788048750135178">Откройте меню Chrome, нажмите "Настройки &gt; Показать дополнительные настройки &gt; Личные данные" и отключите функцию "Запрашивать настройки и файлы для ускорения загрузки страниц". Если устранить проблему не удалось, снова установите флажок, чтобы страницы загружались быстрее.</translation>
+<translation id="6341737370356890233">Откройте меню Chrome, нажмите "<ph name="SETTINGS_TITLE" />" &gt; "<ph name="ADVANCED_TITLE" />" и снимите флажок "<ph name="NO_PREFETCH_DESCRIPTION" />". Если устранить проблему не удалось, снова установите флажок, чтобы страницы загружались быстрее.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_sk.xtb b/chromium/components/strings/components_google_chrome_strings_sk.xtb
new file mode 100644
index 00000000000..7058ada7cb0
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_sk.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sk">
+<translation id="130631256467250065">Zmeny sa prejavia po ďalšom reštartovaní zariadenia.</translation>
+<translation id="3140883423282498090">Zmeny sa prejavia pri nasledujúcom reštartovaní prehliadača Google Chrome.</translation>
+<translation id="5423788048750135178">Prejdite do Ponuky Chrome &gt; Nastavenia &gt; (Rozšírené) Ochrana osobných údajov
+ a zakážte možnosť Predbežne vyvolať zdroje stránky.
+ Ak týmto postupom daný problém nevyriešite, odporúčame vám túto možnosť
+ znova povoliť, aby ste získali lepšiu výkonnosť.</translation>
+<translation id="6341737370356890233">Prejdite do
+ ponuky Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ a zrušte výber položky <ph name="NO_PREFETCH_DESCRIPTION" />.
+ Ak to problém nevyrieši, odporúčame túto možnosť znova vybrať,
+ aby ste získali lepšiu výkonnosť.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_sl.xtb b/chromium/components/strings/components_google_chrome_strings_sl.xtb
new file mode 100644
index 00000000000..4ab38150690
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_sl.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sl">
+<translation id="130631256467250065">Spremembe bodo uveljavljene pri naslednjem vnovičnem zagonu naprave.</translation>
+<translation id="3140883423282498090">Spremembe bodo začele veljati ob naslednjem zagonu Google Chroma.</translation>
+<translation id="5423788048750135178">Odprite Chromov meni &gt; Nastavitve &gt; (Dodatno) Zasebnost
+ in onemogočite »Vnaprej prenesi sredstva strani«.
+ Če s tem ne odpravite težave, priporočamo, da možnost znova
+ omogočite zaradi izboljšanega delovanja.</translation>
+<translation id="6341737370356890233">Odprite
+ Chromov meni &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ in počistite polje »<ph name="NO_PREFETCH_DESCRIPTION" />«.
+ Če s tem težave ne odpravite, priporočamo, da to možnost
+ znova izberete.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_sr.xtb b/chromium/components/strings/components_google_chrome_strings_sr.xtb
new file mode 100644
index 00000000000..6c19406787c
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_sr.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sr">
+<translation id="130631256467250065">Промене ће ступити на снагу када следећи пут поново покренете уређај.</translation>
+<translation id="3140883423282498090">Промене ће ступити на снагу када следећи пут поново покренете Google Chrome.</translation>
+<translation id="5423788048750135178">Отворите Chrome мени &gt; Подешавања &gt; (Напредне опције) Приватност
+ и онемогућите „Припреми учитавање ресурса странице“.
+ Ако вам то не реши проблем, препоручујемо да поново омогућите
+ ову опцију ради бољих перформанси.</translation>
+<translation id="6341737370356890233">Отворите
+ Chromе мени &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ и опозовите избор опције „<ph name="NO_PREFETCH_DESCRIPTION" />“.
+ Ако вам то не реши проблем, препоручујемо да поново изаберете
+ ову опцију ради бољих перформанси.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_sv.xtb b/chromium/components/strings/components_google_chrome_strings_sv.xtb
new file mode 100644
index 00000000000..798c2cbd6dc
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_sv.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sv">
+<translation id="130631256467250065">Dina ändringar börjar gälla nästa gång du startar om enheten.</translation>
+<translation id="3140883423282498090">Ändringarna börjar gälla nästa gång du startar Google Chrome.</translation>
+<translation id="5423788048750135178">Öppna Chrome-menyn &gt; Inställningar &gt; (Avancerat) Sekretess
+ och inaktivera Förhandshämta sidresurser.
+ Om det inte hjälper rekommenderar vi att du aktiverar alternativet
+ igen vilket ger bättre prestanda.</translation>
+<translation id="6341737370356890233">Öppna
+ Chrome-menyn &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ och avmarkera <ph name="NO_PREFETCH_DESCRIPTION" />.
+ Om det inte hjälper rekommenderar vi att du markerar det
+ här alternativet igen så att funktionaliteten förbättras.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_sw.xtb b/chromium/components/strings/components_google_chrome_strings_sw.xtb
new file mode 100644
index 00000000000..1a0cbadb66f
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_sw.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sw">
+<translation id="130631256467250065">Mabadiliko yako yatatekelezwa utakapowasha upya tena kifaa chako.</translation>
+<translation id="3140883423282498090">Mabadiliko yako yataanza kufanya kazi wakati ujao utakapozindua Google Chrome.</translation>
+<translation id="5423788048750135178">Nenda kwenye menyu ya Chrome &gt; Mipangilio &gt; Faragha (Iliyoboreshwa)
+ na uzime "Leta mapema rasilimali za kurasa."
+ Ikiwa hili halitatui tatizo, tunapendekeza uwashe chaguo hili
+ tena kwa utendaji ulioimarishwa.</translation>
+<translation id="6341737370356890233">Nenda kwenye
+ menyu ya Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ na uondoe tiki kwenye "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Ikiwa hili halitatatua tatizo, tunapendekeza uchague tena chaguo hili kwa utendaji ulioboreshwa.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_ta.xtb b/chromium/components/strings/components_google_chrome_strings_ta.xtb
new file mode 100644
index 00000000000..57154bef856
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_ta.xtb
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ta">
+<translation id="130631256467250065">அடுத்த முறை உங்கள் சாதனத்தை மறுதொடக்கம் செய்யும்போது, மாற்றங்கள் செயல்பாட்டிற்கு வரும்.</translation>
+<translation id="3140883423282498090">அடுத்த முறை Google Chrome ஐ மீண்டும் தொடங்கியவுடன் உங்கள் மாற்றங்கள் செயல்படும்.</translation>
+<translation id="5423788048750135178">Chrome மெனு &gt; அமைப்புகள் &gt; (மேம்படுத்தப்பட்டது) தனியுரிமை என்பதற்குச் சென்று,
+ "பக்க மூலங்களைப் பெறு" என்பதை முடக்கவும்.
+ இது சிக்கலைத் தீர்க்கவில்லை எனில், மேம்பட்ட செயல்பாட்டிற்கு இந்த விருப்பத்தை
+ மீண்டும் இயக்கும்படி பரிந்துரைக்கிறோம்.</translation>
+<translation id="6341737370356890233">Chrome மெனு &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ என்பதற்குச் சென்று, "<ph name="NO_PREFETCH_DESCRIPTION" />" என்பதைத் தேர்வுநீக்கம் செய்யவும்.
+ இது சிக்கலைத் தீர்க்கவில்லை எனில், மேம்பட்ட செயல்பாட்டிற்கு இந்த விருப்பத்தை மீண்டும் தேர்ந்தெடுக்கும்படி பரிந்துரைக்கிறோம்.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_te.xtb b/chromium/components/strings/components_google_chrome_strings_te.xtb
new file mode 100644
index 00000000000..f73936a72fd
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_te.xtb
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="te">
+<translation id="130631256467250065">మీ మార్పులు మీరు మీ పరికరాన్ని పునఃప్రారంభించే తదుపరిసారి ప్రభావవంతం అవుతాయి.</translation>
+<translation id="3140883423282498090">మీ మార్పులు మీరు Google Chromeను మళ్లీ ప్రారంభించినప్పుడు ప్రభావాన్ని చూపుతాయి.</translation>
+<translation id="5423788048750135178">Chrome మెను &gt; సెట్టింగ్‌లు &gt; (అధునాతనం) గోప్యతకి వెళ్లి,
+ "పేజీ వనరులను ముందుగానే పొందండి" ఎంపిక నిలిపివేయండి.
+ దీని వలన సమస్య పరిష్కారం కాకపోతే, మెరుగైన పనితీరు కోసం ఈ ఎంపికను
+ మీరు మళ్లీ ప్రారంభించాలని మేము సిఫార్సు చేస్తున్నాము.</translation>
+<translation id="6341737370356890233">Chrome మెను &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />కి వెళ్లండి,
+ ఆపై "<ph name="NO_PREFETCH_DESCRIPTION" />" ఎంపికను తీసివేయండి.
+ దీని వల్ల సమస్య పరిష్కారం కాకుంటే, మెరుగైన పనితీరు కోసం మీరు
+ ఈ ఎంపికను మళ్లీ ఎంచుకోవాలని మేము సిఫార్సు చేస్తున్నాము.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_th.xtb b/chromium/components/strings/components_google_chrome_strings_th.xtb
new file mode 100644
index 00000000000..fa13ef7c1ea
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_th.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="th">
+<translation id="130631256467250065">การเปลี่ยนแปลงของคุณจะมีผลในครั้งถัดไปที่คุณรีสตาร์ทอุปกรณ์ของคุณ</translation>
+<translation id="3140883423282498090">การเปลี่ยนแปลงของคุณจะมีผลในครั้งถัดไปที่คุณเปิด Google Chrome</translation>
+<translation id="5423788048750135178">ไปที่เมนู Chrome &gt; การตั้งค่า &gt; ความเป็นส่วนตัว (ขั้นสูง)
+ และปิดใช้ "ดึงทรัพยากรบนหน้าล่วงหน้า"
+ หากวิธีนี้ไม่ช่วยแก้ปัญหา เราขอแนะนำให้เปิดใช้ตัวเลือกนี้
+ อีกครั้งเพื่อให้ประสิทธิภาพการทำงานดียิ่งขึ้น</translation>
+<translation id="6341737370356890233">ไปที่
+ เมนู Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ และยกเลิกการเลือก "<ph name="NO_PREFETCH_DESCRIPTION" />"
+ หากการกระทำดังกล่าวไม่ช่วยแก้ไขปัญหา เราขอแนะนำให้เลือกตัวเลือกนี้
+ อีกครั้งเพื่อให้ประสิทธิภาพการทำงานดียิ่งขึ้น</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_tr.xtb b/chromium/components/strings/components_google_chrome_strings_tr.xtb
new file mode 100644
index 00000000000..e1a63f1da82
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_tr.xtb
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="tr">
+<translation id="130631256467250065">Yaptığınız değişiklikler cihazı yeniden başlattığınızda etkinleşecektir.</translation>
+<translation id="3140883423282498090">Yaptığınız değişiklikler Google Chrome'u yeniden başlattığınızda geçerli olacak.</translation>
+<translation id="5423788048750135178">Chrome menüsü &gt; Ayarlar &gt; (Gelişmiş) Gizlilik'e gidin
+ ve "Sayfa kaynaklarını ön getir"in işaretini kaldırın.
+ Bu işlem sorunu çözmezse performansın iyileşmesi için bu seçeneği tekrar
+ etkinleştirmenizi öneririz.</translation>
+<translation id="6341737370356890233">Chrome menüsü &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" /> öğesine gidin
+ ve "<ph name="NO_PREFETCH_DESCRIPTION" />" seçeneğinin işaretini kaldırın.
+ Bu işlem sorunu çözmezse performansın iyileşmesi için bu seçeneği tekrar işaretlemenizi öneririz.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_uk.xtb b/chromium/components/strings/components_google_chrome_strings_uk.xtb
new file mode 100644
index 00000000000..d55f3fd8f34
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_uk.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="uk">
+<translation id="130631256467250065">Ваші зміни почнуть діяти під час наступного перезапуску пристрою.</translation>
+<translation id="3140883423282498090">Ваші зміни почнуть діяти після наступного перезапуску Google Chrome.</translation>
+<translation id="5423788048750135178">Перейдіть у меню Chrome &gt; Налаштування &gt; (Розширені) Конфіденційність
+ і вимкніть опцію "Заздалегідь отримувати ресурси сторінки".
+ Якщо проблема не зникне, радимо знову ввімкнути цю опцію,
+ щоб покращити стабільність.</translation>
+<translation id="6341737370356890233">Перейдіть у
+ меню Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ і зніміть прапорець біля опції "<ph name="NO_PREFETCH_DESCRIPTION" />".
+ Якщо проблема не зникне, радимо знову вибрати цю опцію,
+ щоб покращити стабільність.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_vi.xtb b/chromium/components/strings/components_google_chrome_strings_vi.xtb
new file mode 100644
index 00000000000..0e5af57da7e
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_vi.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="vi">
+<translation id="130631256467250065">Thay đổi của bạn sẽ có hiệu lực vào lần tiếp theo bạn khởi động lại thiết bị của mình.</translation>
+<translation id="3140883423282498090">Thay đổi của bạn sẽ có hiệu lực vào lần tiếp theo bạn chạy lại Google Chrome.</translation>
+<translation id="5423788048750135178">Chuyển đến menu Chrome &gt; Cài đặt &gt; Bảo mật (Nâng cao)
+ và tắt "Tìm nạp trước tài nguyên trang".
+ Nếu cách này không giải quyết được sự cố thì chúng tôi khuyên bạn nên bật lại tùy chọn này
+ để cải thiện hiệu suất.</translation>
+<translation id="6341737370356890233">Chuyển đến
+ menu Chrome &gt;
+ <ph name="SETTINGS_TITLE" />
+ &gt;
+ <ph name="ADVANCED_TITLE" />
+ và bỏ chọn "<ph name="NO_PREFETCH_DESCRIPTION" />."
+ Nếu cách này không giải quyết được sự cố thì chúng tôi khuyên bạn nên chọn lại tùy chọn này
+ để cải thiện hiệu suất.</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_zh-CN.xtb b/chromium/components/strings/components_google_chrome_strings_zh-CN.xtb
new file mode 100644
index 00000000000..330ba36782a
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_zh-CN.xtb
@@ -0,0 +1,9 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="zh-CN">
+<translation id="130631256467250065">您所做的更改会在下次重新启动设备时生效。</translation>
+<translation id="3140883423282498090">您所做的更改会在下次重新启动 Google Chrome 时生效。</translation>
+<translation id="5423788048750135178">前往 Chrome 菜单 &gt;“设置”&gt;“隐私设置”(高级设置)部分,然后停用“预提取网页资源”。
+ 如果这无法解决该问题,我们建议您重新启用此选项,以便改善性能。</translation>
+<translation id="6341737370356890233">前往 Chrome 菜单 &gt;“<ph name="SETTINGS_TITLE" />”&gt;“<ph name="ADVANCED_TITLE" />”部分,然后取消选中“<ph name="NO_PREFETCH_DESCRIPTION" />”。如果这无法解决该问题,我们建议您重新选中此选项,以便改善性能。</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_zh-TW.xtb b/chromium/components/strings/components_google_chrome_strings_zh-TW.xtb
new file mode 100644
index 00000000000..bd2d9e72607
--- /dev/null
+++ b/chromium/components/strings/components_google_chrome_strings_zh-TW.xtb
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="zh-TW">
+<translation id="130631256467250065">您的變更會在下次重新啟動裝置時生效。</translation>
+<translation id="3140883423282498090">您的變更將於下次重新啟動 Google Chrome 時生效。</translation>
+<translation id="5423788048750135178">前往 Chrome 選單 &gt; [設定] &gt; (進階) [隱私權]
+ 停用 [預先擷取網頁資源]。
+ 如果仍然無法解決問題,建議您重新啟用這個選項,
+ 讓 Chrome 的效能更優異。</translation>
+<translation id="6341737370356890233">前往
+ Chrome 選單 &gt;
+ [<ph name="SETTINGS_TITLE" />]
+ &gt;
+ [<ph name="ADVANCED_TITLE" />]
+ 然後取消勾選 [<ph name="NO_PREFETCH_DESCRIPTION" />]。
+ 如果仍然無法解決問題,建議您重新勾選這個選項
+ 以增進效能。</translation>
+</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_am.xtb b/chromium/components/strings/components_strings_am.xtb
index bacda59116b..5fc988fa48d 100644
--- a/chromium/components/strings/components_strings_am.xtb
+++ b/chromium/components/strings/components_strings_am.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="am">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="am">
+<translation id="1032854598605920125">በሰዓት አቅጣጫ አሽከርክር</translation>
<translation id="1055184225775184556">&amp;አክልን ቀልብስ</translation>
<translation id="106701514854093668">የዴስክቶፕ ዕልባቶች</translation>
-<translation id="1103523840287552314">ሁልጊዜ <ph name="LANGUAGE"/>ን መተርጎም</translation>
+<translation id="1080116354587839789">ከስፋቱ ጋር አመጣጥን</translation>
+<translation id="1103523840287552314">ሁልጊዜ <ph name="LANGUAGE" />ን መተርጎም</translation>
<translation id="1113869188872983271">&amp;እንደገና ደርድርን ቀልብስ</translation>
<translation id="111844081046043029">እርግጠኛ ነዎት ይህን ገጽ መተው ይፈልጋሉ?</translation>
<translation id="112840717907525620">የመምሪያ መሸጎጫ እሺ</translation>
<translation id="1132774398110320017">የChrome ራስ-ሙላ ቅንብሮች...</translation>
-<translation id="1152921474424827756">የ<ph name="URL"/> <ph name="BEGIN_LINK"/>የተሸጎጠ ቅጂ<ph name="END_LINK"/> ይድረሱ</translation>
+<translation id="1150979032973867961">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በኮምፒውተርዎ ስርዓተ ክወና የሚታመን አይደለም። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
+<translation id="1152921474424827756">የ<ph name="URL" /> <ph name="BEGIN_LINK" />የተሸጎጠ ቅጂ<ph name="END_LINK" /> ይድረሱ</translation>
+<translation id="121201262018556460"><ph name="DOMAIN" />ን ለመድረስ ሞክረዋል፣ ግን አገልጋዩ ደካማ ቁልፍ የያዘ የእውቅና ማረጋገጫ ነው ያቀረበው። አንድ አጥቂ የግል ቁልፉን ሰብሮ ሊሆን ይችላል፣ እና አገልጋዩ የጠበቁት ላይሆን ይችላል (ከአጥቂ ጋር እየተገናኙ ሊሆኑ ይችላሉ)።</translation>
<translation id="1227224963052638717">ያልታወቀ መመሪያ።</translation>
<translation id="1227633850867390598">እሴት ይደብቁ</translation>
<translation id="1228893227497259893">የተሳሳተ የምንነት ለዪ</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">የምዝገባ ጎራ፦</translation>
<translation id="1344588688991793829">የChromium ራስ-ሙላ ቅንብሮች...</translation>
<translation id="1426410128494586442">አዎ</translation>
+<translation id="1430915738399379752">አትም</translation>
<translation id="1455235771979731432">የእርስዎን ካርድ ማረጋገጥ ላይ ችግር ነበር። የእርስዎን የበይነመረብ ግንኙነት ይፈትሹ እና እንደገና ይሞክሩ።</translation>
<translation id="1491151370853475546">ይህን ገጽ ዳግም ይጫኑ</translation>
<translation id="1549470594296187301">ይህን ባህሪ ለመጠቀም ጃቫስክሪፕት መንቃት አለበት።</translation>
-<translation id="1639239467298939599">በመጫን ላይ</translation>
<translation id="1640180200866533862">የተጠቃሚ መምሪያዎች</translation>
<translation id="1644184664548287040">የአውታረ መረቡ ውቅር ልክ ያልሆነ እና ሊመጣ የማይችል ነው።</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> ላይ ያለው ገጽ እንዲህ ይላል፦</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="168841957122794586">የአገልጋይ እውቅና ማረጋገጫው ደካማ የሆነ ባለስውር መረጃ ቁልፍ ነው ያለው።</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> ላይ ያለው ገጽ እንዲህ ይላል፦</translation>
+<translation id="1706954506755087368">{1,plural, =1{ይህ አገልጋይ <ph name="DOMAIN" /> እንደሆነ ማረጋገጥ አልቻለም፤ የደህንነት ማረጋገጫ እውቅና ማረጋገጫው ከነገ የመጣ ነው ይላል። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።}one{ይህ አገልጋይ <ph name="DOMAIN" /> እንደሆነ ማረጋገጥ አልቻለም፤ የደህንነት ማረጋገጫ እውቅና ማረጋገጫው የወደፊት # ቀንኖች የመጣ ነው ይላል። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።}other{ይህ አገልጋይ <ph name="DOMAIN" /> እንደሆነ ማረጋገጥ አልቻለም፤ የደህንነት ማረጋገጫ እውቅና ማረጋገጫው የወደፊት # ቀንኖች የመጣ ነው ይላል። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በመሣሪያዎ ስርዓተ ክወና የሚታመን አይደለም። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
<translation id="1821930232296380041">ልክ ያልሆነ ጥያቄ ወይም የጥያቄ ልኬቶች</translation>
-<translation id="1853748787962613237">ጽሑፉን ማሳየት አልተቻለም።</translation>
<translation id="1871208020102129563">የ.pac ስክሪፕት ዩአርኤል ሳይሆን ተኪ አገልጋዮችን እንዲጠቀም ነው ተኪ የተዋቀረው።</translation>
-<translation id="1875753206475436906">ራስ-አስተማሪ አይነት፦ <ph name="HEURISTIC_TYPE"/>
- የአገልጋይ አይነት፦ <ph name="SERVER_TYPE"/>
- የመስክ ፊርማ፦ <ph name="FIELD_SIGNATURE"/>
- የቅጽ ፊርማ፦ <ph name="FORM_SIGNATURE"/>
- የሙከራ መታወቂያ፦ «<ph name="EXPERIMENT_ID"/>»</translation>
-<translation id="194030505837763158">ወደ <ph name="LINK"/> ሂድ</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> እልባቶች</translation>
+<translation id="194030505837763158">ወደ <ph name="LINK" /> ሂድ</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> እልባቶች</translation>
<translation id="1973335181906896915">የመለያ ቁጥር መስጠት ላይ ስህተት</translation>
+<translation id="1974060860693918893">የላቀ</translation>
<translation id="2025186561304664664">ተኪ ወደ ራስ-ውቅር ተዋቅሯል።</translation>
<translation id="2025623846716345241">ዳግም መጫን ያረጋግጡ</translation>
-<translation id="2030481566774242610"><ph name="LINK"/>ን ማለትዎ ነው?</translation>
+<translation id="2030481566774242610"><ph name="LINK" />ን ማለትዎ ነው?</translation>
<translation id="2053553514270667976">ዚፕ ኮድ</translation>
<translation id="20817612488360358">የስርዓት ተኪ ቅንብሮች ስራ ላይ እንዲውሉ ተቀናብረዋል ግን ግልጽ የሆነ የተኪ ውቅርም ተገልጿል።</translation>
<translation id="2094505752054353250">የጎራ አለመዛመድ</translation>
<translation id="2096368010154057602">ክፍል</translation>
<translation id="2113977810652731515">ካርታ</translation>
-<translation id="2114841414352855701">በ<ph name="POLICY_NAME"/> ስለተሻረ ችላ ተብሏል።</translation>
+<translation id="2114841414352855701">በ<ph name="POLICY_NAME" /> ስለተሻረ ችላ ተብሏል።</translation>
+<translation id="2128531968068887769">ቤተኛ ደንበኛ</translation>
<translation id="213826338245044447">የተንቀሳቃሽ ስልክ ዕልባቶች</translation>
+<translation id="2171101176734966184"><ph name="DOMAIN" />ን ለመድረስ ሞክረዋል፣ ነገር ግን አገልጋዩ ደካማ የፊርማ ስልተቀመር በመጠቀም የተፈረመ የእውቅና ማረጋገጫ ነው ያረጋገጠው። ይህም ማለት አገልጋዩ ያቀረበው የደህንነት ምስክርነቶች የተጭበረበሩ ሊሆኑ ይችላሉ፣ እናም አገልጋዩ እርስዎ የሚጠብቁት አገልጋይ ላይሆን ይችላል (ከአጥቂ ጋር እየተገናኙ ሊሆን ይችላል)።</translation>
<translation id="2181821976797666341">መምሪያዎች</translation>
<translation id="2212735316055980242">መመሪያ አልተገኘም</translation>
<translation id="2213606439339815911">ግቤቶችን በማምጣት ላይ...</translation>
<translation id="225207911366869382">ይህ ዋጋ ለዚህ መመሪያ ተቋርጧል።</translation>
<translation id="2262243747453050782">የኤች ቲ ቲ ፒ ስህተት</translation>
-<translation id="2270192940992995399">ጽሑፉን ማግኘት አልተቻለም።</translation>
-<translation id="2328300916057834155">ችላ የተባለ የመረጃ ጠቋሚ <ph name="ENTRY_INDEX"/> ልክ ያልሆነ እልባት</translation>
+<translation id="2282872951544483773">የማይገኙ ሙከራዎች</translation>
+<translation id="229702904922032456">የአንድ የስር ወይም መሃከል እውቅና ማረጋገጫ ጊዜው አልፎበታል።</translation>
+<translation id="2328300916057834155">ችላ የተባለ የመረጃ ጠቋሚ <ph name="ENTRY_INDEX" /> ልክ ያልሆነ እልባት</translation>
<translation id="2354001756790975382">ሌላ እልባቶች</translation>
<translation id="2359808026110333948">ቀጥል</translation>
<translation id="2367567093518048410">ደረጃ</translation>
+<translation id="2384307209577226199">የንግድ ድርጅት ነባሪ</translation>
+<translation id="2386255080630008482">የአገልጋይ እውቅና ማረጋገጫ ተሽሯል።</translation>
<translation id="2392959068659972793">ምንም እሴት ያልተዋቀረላቸው መምሪያዎችን አሳይ</translation>
<translation id="2396249848217231973">&amp;ስረዛን ቀልብስ</translation>
+<translation id="2413528052993050574">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው ተሽሮ ሊሆን ይችላል። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
<translation id="2455981314101692989">ይህ ድረ-ገጽ ለዚህ ቅጽ ራስ-መሙላትን አሰናክሏል።</translation>
<translation id="2479410451996844060">ልክ ያልሆነ የፍለጋ ዩአርኤል።</translation>
+<translation id="2491120439723279231">የአገልጋይ እውቅና ማረጋገጫ ስህተቶችን ይዟል።</translation>
<translation id="2495083838625180221">JSON ተንታኝ</translation>
<translation id="2498091847651709837">አዲስ ካርድ ቃኝ</translation>
<translation id="2556876185419854533">&amp;አርትዕን ቀልብስ</translation>
-<translation id="2581221116934462656">ቀጣዩ ጊዜ ላይ <ph name="PRODUCT_NAME"/> በዚህ ጣቢያ ያሉ የ<ph name="LANGUAGE_NAME"/> ገጾችን እንዲተረጉምልዎ ይፈልጋሉ?</translation>
+<translation id="2581221116934462656">ቀጣዩ ጊዜ ላይ <ph name="PRODUCT_NAME" /> በዚህ ጣቢያ ያሉ የ<ph name="LANGUAGE_NAME" /> ገጾችን እንዲተረጉምልዎ ይፈልጋሉ?</translation>
<translation id="2587841377698384444">የማውጫ የኤፒአይ መታወቂያ፦</translation>
<translation id="2597378329261239068">ይህ ሰነድ በይለፍ ቃል የተጠበቀ ነው። እባክዎ የይለፍ ቃል ያስገቡ።</translation>
+<translation id="2625385379895617796">የእርስዎ ሰዓት ገና የወደፊት ነው</translation>
<translation id="2639739919103226564">ሁኔታ፦</translation>
+<translation id="2653659639078652383">አስገባ</translation>
<translation id="2704283930420550640">ዋጋ ከቅርጸት ጋር አይዛመድም።</translation>
<translation id="2721148159707890343">ጥያቄ ተሳክቷል</translation>
+<translation id="2728127805433021124">የአገልጋዩ እውቅና ማረጋገጫ የተፈረመው በደካማ የፊርማ ስልተቀመር ነው።</translation>
<translation id="2774256287122201187">መቀጠል ይችላሉ። ወደ ገጹ ከቀጠሉ፣ ይህ ማስጠንቀቂያ ለአምስት ደቂቃዎች ዳግመኛ አይታይም።</translation>
<translation id="277499241957683684">የሚጎድል የመሣሪያ መዝገብ</translation>
<translation id="2835170189407361413">ቅጽ አጽዳ</translation>
-<translation id="2855922900409897335">የእርስዎን <ph name="CREDIT_CARD"/> ያረጋግጡ</translation>
+<translation id="2855922900409897335">የእርስዎን <ph name="CREDIT_CARD" /> ያረጋግጡ</translation>
+<translation id="2915500479781995473">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው ጊዜ አልፎበታል። ይሄ በተሳሳተ ውቅር ወይም ግንኙነትዎን እየጠለፈ ባለ አንድ አጥቂ የተከሰተ ሊሆን ይችላል። የኮምፒውተርዎ ሰዓት በአሁኑ ጊዜ ወደ <ph name="CURRENT_TIME" /> ተዋቅሯል። ትክክል ይመስላል? ካልሆነ የስርዓትዎን ሰዓት አስተካክለው ይህን ገጽ ማደስ አለብዎት።</translation>
+<translation id="2922350208395188000">የአገልጋይ እውቅና ማረጋገጫ ሊረጋገጥ አልቻለም።</translation>
+<translation id="2941952326391522266">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በ<ph name="DOMAIN2" /> ነው የተሰጠው። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
<translation id="2958431318199492670">የአውታረ መረብ ውቅሩ በኦ ኤን ሲ መስፈርቱ አይገዛም። አንዳንድ የውቅሩ ክፍሎች ላይመጡ ይችላሉ።</translation>
<translation id="2972581237482394796">&amp;ድገም</translation>
-<translation id="3010559122411665027">የዝርዝር ግቤት «<ph name="ENTRY_INDEX"/>»፦ <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">የዝርዝር ግቤት «<ph name="ENTRY_INDEX" />»፦ <ph name="ERROR" /></translation>
<translation id="3024663005179499861">የተሳሳተ የመምሪያ አይነት</translation>
<translation id="3105172416063519923">የእሴት መታወቂያ፦</translation>
<translation id="3145945101586104090">ምላሹን መግለጥ አልተሳካም</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">ደሴት</translation>
<translation id="3219579145727097045">የጊዜ ማብቂያ ቀን እና በካርድዎ ፊት ላይ ያለውን ባለ4 አኃዝ CVCን ያስገቡ</translation>
-<translation id="3228969707346345236">ገጹ አስቀድሞ በ<ph name="LANGUAGE"/> ስለሆነ ትርጉሙ አልተሳካም።</translation>
+<translation id="3225919329040284222">አገልጋዩ አብረው የተሰሩ የሚጠበቁ ማሟያዎችን የማያሟላ የእውቅና ማረጋገጫ ነው ያቀረበው። እነዚህ የሚጠበቁ ማሟያዎች እርስዎን ለመጠበቅ ለተረጋገጡ ከፍተኛ ደህንነት ላላቸው ድር ጣቢያዎች ተካትተዋል።</translation>
+<translation id="3228969707346345236">ገጹ አስቀድሞ በ<ph name="LANGUAGE" /> ስለሆነ ትርጉሙ አልተሳካም።</translation>
<translation id="3270847123878663523">&amp;ዳግም ደርድርን ቀልብስ</translation>
+<translation id="3286538390144397061">አሁን ዳግም አስጀምር</translation>
<translation id="333371639341676808">ይህ ገጽ ተጨማሪ ማገናኛዎችን እንዳይፈጥር አግድ።</translation>
-<translation id="3369366829301677151">የእርስዎን <ph name="CREDIT_CARD"/> ያዘምኑ እና ያረጋግጡ</translation>
+<translation id="3340978935015468852">ቅንብሮች</translation>
+<translation id="3369192424181595722">የሰዓት ስህተት</translation>
+<translation id="3369366829301677151">የእርስዎን <ph name="CREDIT_CARD" /> ያዘምኑ እና ያረጋግጡ</translation>
<translation id="337363190475750230">አቅርቦት ተቋርጧል</translation>
<translation id="3377188786107721145">የመምሪያ ትንተና ስህተት</translation>
<translation id="3380365263193509176">ያልታወቀ ስህተት</translation>
<translation id="3380864720620200369">የደንበኛ መታወቂያ፦</translation>
<translation id="3427342743765426898">&amp;አርትዕን ድገም</translation>
+<translation id="3435896845095436175">አንቃ</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">የሚመጣው በየ፦</translation>
+<translation id="3462200631372590220">የላቁ ደብቅ</translation>
+<translation id="3528171143076753409">የአገልጋይ እውቅና ማረጋገጫ የታመነ አይደለም።</translation>
<translation id="3542684924769048008">የይለፍ ቃል ይጠቀሙ ለ፦</translation>
<translation id="3583757800736429874">&amp;ውሰድን ድገም</translation>
<translation id="3623476034248543066">እሴት አሳይ</translation>
+<translation id="3648607100222897006">እነዚህ የሙከራ ባህሪያት በማንኛውም ጊዜ ሊቀየሩ፣ ሊሰበሩ ወይም ሊጠፉ ይችላሉ። ከእነዚህ ሙከራዎች ውስጥ አንዱን ቢያበሩት ምን ሊከሰት እንደሚችል ምንም አይነት ዋስትናዎችን አንሰጥም፣ እንዲያውም አሳሽዎ ድንገት ሊቃጠል ሁሉ ይችላል። ቀልዱን እንተወውና አሳሽዎ ሁሉንም ውሂብዎን ሊሰርዘው ይችላል ወይም ደግሞ ደህንነትዎ እና ግላዊነትዎ ባልተጠበቁ መንገዶች ጥቃት ሊደርስባቸው ይችላል። የሚያነቋቸውን ማንኛውም ሙከራዎች ለሁሉም የዚህ አሳሽ ተጠቃሚ ነው የሚነቁት። እባክዎ በጥንቃቄ ይቀጥሉ።</translation>
<translation id="3650584904733503804">ማረጋገጥ ተሳክቷል</translation>
<translation id="370665806235115550">በመጫን ላይ...</translation>
<translation id="3712624925041724820">ሁሉም ፍቃዶች ተሞክረዋል</translation>
<translation id="3739623965217189342">እርስዎ የቀዱት አገናኝ</translation>
<translation id="375403751935624634">በአገልጋይ ስህተት ምክንያት የትርጉም ስራው ተሰናክሏል።</translation>
<translation id="385051799172605136">ተመለስ</translation>
+<translation id="3858027520442213535">ቀን እና ሰዓትን አዘምን</translation>
<translation id="3884278016824448484">የሚጋጭ የመሣሪያ ለዪ</translation>
<translation id="3885155851504623709">ቤተ-ክህነት አካባቢ</translation>
<translation id="3934680773876859118">የፒ ዲ ኤፍ ሰነድ መጫን አልተሳካም</translation>
<translation id="3963721102035795474">የአንባቢ ሁነታ</translation>
<translation id="4030383055268325496">&amp;አክልን ቀልብስ</translation>
-<translation id="4058922952496707368">ቁልፍ «<ph name="SUBKEY"/>»፦ <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ማስጠንቀቂያ</translation>
+<translation id="4058922952496707368">ቁልፍ «<ph name="SUBKEY" />»፦ <ph name="ERROR" /></translation>
<translation id="4079302484614802869">የተኪ ውቅር ቋሚ አገልጋዮችን ሳይሆን የ.pac ስክሪፕት ዩአርኤል ለመጠቀም ነው የተዋቀረው።</translation>
<translation id="409504436206021213">ዳግም አትጫን</translation>
<translation id="4103249731201008433">የመሣሪያ መለያ ቁጥር ልክ ያልሆነ ነው</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">መጥፎ ፊርማ</translation>
<translation id="4269787794583293679">(ምንም የተጠቃሚ ስም የለም)</translation>
<translation id="4300246636397505754">የወላጅ አስተያየት ጥቆማዎች</translation>
-<translation id="4372948949327679948">የተጠበቀው የ<ph name="VALUE_TYPE"/> ዋጋ ነው።</translation>
+<translation id="4325863107915753736">ጽሑፉን ማግኘት አልተቻለም</translation>
+<translation id="4372948949327679948">የተጠበቀው የ<ph name="VALUE_TYPE" /> ዋጋ ነው።</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" />ን ለመድረስ ሞክረዋል፣ ነገር ግን አገልጋዩ ያቀረበው የእውቅና ማረጋገጫ በሰጪው ተሽሯል። ይህ ማለት አገልጋዩ ያቀረበው የደህንነት ምስክርነቶች ፈጽሞ ሊታመኑ አይገባም። ከአጥቂ ጋር እየተገናኙ ሊሆን ይችላል።</translation>
+<translation id="4394049700291259645">አሰናክል</translation>
+<translation id="4424024547088906515">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በChrome የሚታመን አይደለም። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
<translation id="443673843213245140">የተኪ መጠቀም ተሰናክሏል ግን ግልጽ የሆነ የተኪ ውቅር ተገልጿል።</translation>
-<translation id="4506176782989081258">የማረጋገጥ ስህተት፦ <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">የማረጋገጥ ስህተት፦ <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">አድራሻ ከChrome ይወገድ?</translation>
<translation id="4594403342090139922">&amp;ሰርዝን ቀልብስ</translation>
<translation id="4607653538520819196">ይህ ገጽ በውሂብ አስቀማጭ በኩል ሊተካ አይችልም።</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው ስህተቶች አሉበት። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
<translation id="4726672564094551039">መምሪያዎችን ዳግም ጫን</translation>
+<translation id="4728558894243024398">የመሣሪያ ስርዓት</translation>
+<translation id="4771973620359291008">ያልታወቀ ስህተት ተከስቷል።</translation>
<translation id="4800132727771399293">የእርስዎን የአገልግሎት ማብቂያ ቀን እና CVC ይፈትሹ እና እንደገና ይሞክሩ</translation>
<translation id="4813512666221746211">የአውታረ መረብ ስህተት</translation>
+<translation id="4816492930507672669">ገጹን አመጣጥን</translation>
<translation id="4850886885716139402">አሳይ</translation>
-<translation id="4923417429809017348">ገጹ ከማይታወቅ ቋንቋ ወደ <ph name="LANGUAGE_LANGUAGE"/> ተተርጉሟል</translation>
+<translation id="4923417429809017348">ገጹ ከማይታወቅ ቋንቋ ወደ <ph name="LANGUAGE_LANGUAGE" /> ተተርጉሟል</translation>
<translation id="4926049483395192435">መገለጽ አለበት።</translation>
<translation id="4968547170521245791">ተኪ ማድረግ አይቻልም</translation>
-<translation id="498957508165411911">ከ<ph name="ORIGINAL_LANGUAGE"/> ወደ <ph name="TARGET_LANGUAGE"/> ይተርጎም?</translation>
+<translation id="498957508165411911">ከ<ph name="ORIGINAL_LANGUAGE" /> ወደ <ph name="TARGET_LANGUAGE" /> ይተርጎም?</translation>
<translation id="5019198164206649151">የመጠባበቂያ ማከማቻ በመጥፎ ሁኔታ ላይ</translation>
<translation id="5031870354684148875">ስለ Google ትርጉም</translation>
+<translation id="5045550434625856497">ትክክል ያልሆነ የይለፍ ቃል</translation>
+<translation id="5087286274860437796">የአገልጋይ የዕውቅና ማረጋገጫ በዚህ ጊዜ ላይ የሚሰራ አይደለም።</translation>
<translation id="5089810972385038852">ግዛት</translation>
+<translation id="5094747076828555589">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በChromium የሚታመን አይደለም። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
<translation id="5095208057601539847">ጠቅላይ ግዛት</translation>
<translation id="5145883236150621069">የስህተት ኮድ በመምሪያው ምላሽ ውስጥ አለ</translation>
<translation id="5172758083709347301">ማሽን</translation>
-<translation id="5179510805599951267">በ<ph name="ORIGINAL_LANGUAGE"/> አይደለም? ይህን ስህተት ሪፖርት ያድርጉ</translation>
+<translation id="5179510805599951267">በ<ph name="ORIGINAL_LANGUAGE" /> አይደለም? ይህን ስህተት ሪፖርት ያድርጉ</translation>
<translation id="5190835502935405962">የዕልባቶች አሞሌ</translation>
+<translation id="5199729219167945352">ሙከራዎች</translation>
+<translation id="5251803541071282808">ደመና</translation>
<translation id="5295309862264981122">ዳሰሳን አረጋግጥ</translation>
<translation id="5299298092464848405">መምሪያን መተንተን ላይ ስህተት</translation>
+<translation id="5316812925700871227">በተቃራኒ ሰዓት አቅጣጫ አሽከርክር</translation>
<translation id="5317780077021120954">አስቀምጥ</translation>
<translation id="536296301121032821">የመምሪያ ቅንብሮችን ማከማቸት አልተሳካም</translation>
-<translation id="5439770059721715174">«<ph name="ERROR_PATH"/>» ላይ የብያኔ ማረጋገጥ ስህተት፦ <ph name="ERROR"/></translation>
+<translation id="540969355065856584">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በዚህ ጊዜ ላይ የሚሰራ አይደለም። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
+<translation id="5439770059721715174">«<ph name="ERROR_PATH" />» ላይ የብያኔ ማረጋገጥ ስህተት፦ <ph name="ERROR" /></translation>
<translation id="5455374756549232013">መጥፎ የመምሪያ ጊዜ ማህተም</translation>
<translation id="5470861586879999274">&amp;አርትዕን ድገም</translation>
<translation id="5509780412636533143">የተዳደሩ እልባቶች</translation>
<translation id="5523118979700054094">የመምሪያ ስም</translation>
<translation id="552553974213252141">ጽሑፉ በትክክል ነው የወጣው?</translation>
<translation id="5540224163453853">የተጠየቀውን ጽሑፍ ማግኘት አልተቻለም።</translation>
+<translation id="5556459405103347317">ዳግም ጫን</translation>
<translation id="5565735124758917034">ገባሪ</translation>
<translation id="560412284261940334">አስተዳደር አይደገፍም</translation>
<translation id="5629630648637658800">የመምሪያ ቅንብሮችን መጫን አልተሳካም</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">የአሁኑ ተጠቃሚ</translation>
<translation id="5813119285467412249">&amp;አክልን ድገም</translation>
<translation id="5872918882028971132">የወላጅ አስተያየት ጥቆማዎች</translation>
-<translation id="587701087903783706">ለሞባይል-አመቺ እይታን ይዝጉ</translation>
<translation id="59107663811261420">ይህ የካርድ አይነት ለዚህ ነጋዴ በGoogle ክፍያዎች አይደገፍም። እባክዎ የተለየ ካርድ ይምረጡ።</translation>
+<translation id="5975083100439434680">አሳንስ</translation>
<translation id="5989320800837274978">ቋሚ ተኪ አገልጋዮችም ሆኑ የ.pac ስክሪፕት ዩአርኤል አልተገለጹም።</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">ዝጋ</translation>
+<translation id="6060685159320643512">ይጠንቀቁ፣ እነዚህ ሙከራዎች ሊያስቸግሩ ይችላሉ</translation>
+<translation id="6151417162996330722">የአገልጋይ እውቅና ማረጋገጫው በጣም ረጅም የሆነ የማረጋገጫ ጊዜ አለው።</translation>
<translation id="6154808779448689242">የተመለሰው የመምሪያ ማስመሰያ ከአሁኑ ማስመሰያ ጋር አይዛመድም</translation>
<translation id="6165508094623778733">ተጨማሪ ለመረዳት</translation>
<translation id="6259156558325130047">&amp;ዳግም ደርድርን ድገም</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> እልባቶች</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> እልባቶች</translation>
<translation id="6282194474023008486">የፖስታ ኮድ</translation>
<translation id="6337534724793800597">መምሪያዎችን በስም አጣራ</translation>
+<translation id="6387478394221739770">አዲስ የChrome ባህሪያትን ይፈልጋሉ? የቅድመ ይሁንታ ሰርጣችንን በchrome.com/beta ላይ ይሞክሩት።</translation>
+<translation id="6426993025560594914">ሁሉም ሙከራዎች በመሣሪያ ስርዓትዎ ላይ ይገኛሉ!</translation>
<translation id="6445051938772793705">አገር</translation>
<translation id="6458467102616083041">ነባሪው ፍለጋ በመምሪያ ስለተሰናከለ ችላ ተብሏል።</translation>
<translation id="647261751007945333">የመሣሪያ መምሪያዎች</translation>
<translation id="6512448926095770873">ይህን ገጽ ተወው</translation>
<translation id="6529602333819889595">&amp;ሰርዝን ድገም</translation>
<translation id="6550675742724504774">አማራጮች</translation>
-<translation id="6597614308054261376">ወደ <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> ለመድረስ እየሞከሩ ነው። ይህ ገጽ በዚህ ጊዜ ላይ በውሂብ አስቀማጭ ተኪ ሊደረግ አይችልም።</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> ፍለጋ</translation>
+<translation id="6597614308054261376">ወደ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ለመድረስ እየሞከሩ ነው። ይህ ገጽ በዚህ ጊዜ ላይ በውሂብ አስቀማጭ ተኪ ሊደረግ አይችልም።</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> ፍለጋ</translation>
<translation id="6644283850729428850">ይህ መመሪያ ተቋርጧል።</translation>
<translation id="6646897916597483132">በካርድዎ ፊት ላይ ያለውን ባለ4 አኃዝ CVCን ያስገቡ</translation>
+<translation id="674375294223700098">ያልታወቀ የአገልጋይ እውቅና ማረጋገጫ ስህተት።</translation>
<translation id="6753269504797312559">የመምሪያ እሴት</translation>
<translation id="6831043979455480757">መተርጎም</translation>
<translation id="6839929833149231406">አካባቢ</translation>
<translation id="6874604403660855544">&amp;አክልን ድገም</translation>
<translation id="6891596781022320156">የመመሪያ ደረጃ አይደገፍም።</translation>
<translation id="6915804003454593391">ተጠቃሚ፦</translation>
+<translation id="6957887021205513506">የአገልጋዩ እውቅና ማረጋገጫ የተጭበረበረ ይመስላል።</translation>
<translation id="6965382102122355670">ይሁን</translation>
<translation id="6965978654500191972">መሣሪያ</translation>
<translation id="6970216967273061347">ወረዳ</translation>
<translation id="6973656660372572881">ሁለቱም ቋሚ ተኪ አገልጋዮች እና የ.pac ስክሪፕት ዩአርኤል ተገልጸዋል።</translation>
<translation id="6980028882292583085">የJavaScript ማንቂያ</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250"><ph name="DOMAIN" /> ጋር ለመድረስ ሞክረዋል፣ ነገር ግን አገልጋዩ አስተማማኝ ለመሆን የሚያስቸግር በጣም ረጅም የሆነ የማረጋገጫ ጊዜ ነው ያለው።</translation>
<translation id="7087282848513945231">አውራጃ</translation>
-<translation id="7108649287766967076">ወደ <ph name="TARGET_LANGUAGE"/> መተርጎም አልተሳካም።</translation>
+<translation id="7108649287766967076">ወደ <ph name="TARGET_LANGUAGE" /> መተርጎም አልተሳካም።</translation>
<translation id="7139724024395191329">ኤሚሬት</translation>
+<translation id="7179921470347911571">አሁን ዳግም ያስጀምሩ</translation>
<translation id="7180611975245234373">አድስ</translation>
<translation id="7182878459783632708">ምንም መምሪያዎች አልተዋቀሩም</translation>
-<translation id="7186367841673660872">ይህ ገጽ ከ<ph name="ORIGINAL_LANGUAGE"/>ወደ<ph name="LANGUAGE_LANGUAGE"/>ተተርጉሟል</translation>
+<translation id="7186367841673660872">ይህ ገጽ ከ<ph name="ORIGINAL_LANGUAGE" />ወደ<ph name="LANGUAGE_LANGUAGE" />ተተርጉሟል</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">ስለ <ph name="SEARCH_TERMS"/> ፍለጋ ከ<ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">ስለ <ph name="SEARCH_TERMS" /> ፍለጋ ከ<ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">የእርስዎ የኮምፒዩተር ቀን እና ሰዓት (<ph name="DATE_AND_TIME" />) ልክ ስላልሆኑ የግል ግንኙነት ወደ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ሊመሰረት አይችልም።</translation>
<translation id="7275334191706090484">የተዳደሩ እልባቶች</translation>
<translation id="7298195798382681320">የተመከሩ</translation>
<translation id="7334320624316649418">&amp;ማስተካከልን ድገም</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">ጃቫስክሪፕት</translation>
<translation id="7537536606612762813">ግዴታ</translation>
<translation id="7542995811387359312">ይህ ቅጽ ደህንነቱ የተጠበቀ ግንኙነት ስለማይጠቀም የክሬዲት ካርድ ራስ-መሙላት ተሰናክሏል።</translation>
-<translation id="7568593326407688803">ይህ ገጽ በ<ph name="ORIGINAL_LANGUAGE"/>ነው። መተርጎም ይፈልጋሉ?</translation>
+<translation id="7567204685887185387">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በተጭበረበረ ሁኔታ ተሰጥቶ ሊሆን ይችላል። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
+<translation id="7568593326407688803">ይህ ገጽ በ<ph name="ORIGINAL_LANGUAGE" />ነው። መተርጎም ይፈልጋሉ?</translation>
<translation id="7569952961197462199">ክሬዲት ካርድ ከChrome ይወገድ?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/>ን በጭራሽ አትተርጉም</translation>
-<translation id="7610193165460212391">እሴት ከክልል <ph name="VALUE"/> ውጪ ነው።</translation>
+<translation id="7592362899630581445">የአገልጋዩ እውቅና ማረጋገጫ አንዳንድ ገደቦችን ይጥሳል።</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" />ን በጭራሽ አትተርጉም</translation>
+<translation id="7610193165460212391">እሴት ከክልል <ph name="VALUE" /> ውጪ ነው።</translation>
+<translation id="7674629440242451245">አዲስ የሆኑ አሪፍ የChrome ባህሪያትን ይፈልጋሉ? በ chrome.com/dev ላይ ያለውን የdev ሰርጣችንን ይሞክሩት።</translation>
<translation id="7752995774971033316">አይቀናበርም</translation>
+<translation id="7761701407923456692">የአገልጋይ እውቅና ማረጋገጫ ከዩ አር ኤሉ ጋር አይዛመድም።</translation>
<translation id="777702478322588152">የፕሪፌክት ስልጣን</translation>
<translation id="7791543448312431591">አክል</translation>
<translation id="7805768142964895445">ሁኔታ</translation>
<translation id="7813600968533626083">የአስተያየት ጥቆማ ከChrome ይወገድ?</translation>
<translation id="7887683347370398519">የእርስዎን CVC ይፈትሹ እና እንደገና ይሞክሩ</translation>
<translation id="7935318582918952113">የDOM ማጣሪያ</translation>
+<translation id="7938958445268990899">የአገልጋይ እውቅና ማረጋገጫ ገና አልጸናም።</translation>
<translation id="7956713633345437162">የተንቀሳቃሽ ስልክ ዕልባቶች</translation>
<translation id="7961015016161918242">በፍጹም</translation>
<translation id="7977590112176369853">‹ጥያቄ ያስገቡ›</translation>
-<translation id="7983301409776629893">ሁልጊዜ <ph name="ORIGINAL_LANGUAGE"/>ን ወደ<ph name="TARGET_LANGUAGE"/> መተርጎም</translation>
+<translation id="7983301409776629893">ሁልጊዜ <ph name="ORIGINAL_LANGUAGE" />ን ወደ<ph name="TARGET_LANGUAGE" /> መተርጎም</translation>
<translation id="7988324688042446538">የዴስክቶፕ ዕልባቶች</translation>
<translation id="7995512525968007366">አልተጠቀሰም</translation>
-<translation id="8034522405403831421">ይህ ገጽ በ<ph name="SOURCE_LANGUAGE"/> ነው። ወደ <ph name="TARGET_LANGUAGE"/> ይተርጎም?</translation>
+<translation id="8003882219468422867">የንግድ ድርጅት መሻር</translation>
+<translation id="8034522405403831421">ይህ ገጽ በ<ph name="SOURCE_LANGUAGE" /> ነው። ወደ <ph name="TARGET_LANGUAGE" /> ይተርጎም?</translation>
<translation id="8088680233425245692">ጽሑፉን ማየት አልተቻለም።</translation>
<translation id="8091372947890762290">ማግበር በአገልጋዩ ላይ በመጠባበቅ ላይ ነው</translation>
<translation id="8194797478851900357">&amp;ውሰድን ቀልብስ</translation>
-<translation id="8201077131113104583">የማይሰራ የURL ዝማኔ ለቅጥያ ከመታወቂያ «<ph name="EXTENSION_ID"/>» ጋር።</translation>
+<translation id="8201077131113104583">የማይሰራ የURL ዝማኔ ለቅጥያ ከመታወቂያ «<ph name="EXTENSION_ID" />» ጋር።</translation>
<translation id="8208216423136871611">አታስቀምጥ</translation>
<translation id="8218327578424803826">የተመደበ መገኛ አካባቢ፦</translation>
<translation id="8249320324621329438">ለመጨረሻ ጊዜ የመጣው፦</translation>
+<translation id="8294431847097064396">ምንጭ</translation>
<translation id="8308427013383895095">በአውታረመረብ ግንኙነት ችግር ምክንያት የትርጉም ስራው ተሰናክሏል።</translation>
<translation id="8311778656528046050">እርግጠኛ ነዎት ይህን ገጽ ዳግም መጫን ይፈልጋሉ?</translation>
<translation id="8349305172487531364">የዕልባቶች አሞሌ</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">የሚመለከተው ለ</translation>
<translation id="8530504477309582336">ይህ የካርድ አይነት በGoogle ክፍያዎች አይደገፍም። እባክዎ የተለየ ካርድ ይምረጡ።</translation>
<translation id="8553075262323480129">የገጹ ቋንቋ ሊታወቅ ስላልቻለ ትርጉሙ አልተሳካም።</translation>
-<translation id="8571890674111243710">ገጽ ወደ <ph name="LANGUAGE"/> በመተርጎም ላይ...</translation>
+<translation id="8559762987265718583">የእርስዎ መሣሪያ ቀን (<ph name="DATE_AND_TIME" />) ልክ ስላልሆነ ወደ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> የግል ግንኙነት መመስረት አይቻልም።</translation>
+<translation id="8571890674111243710">ገጽ ወደ <ph name="LANGUAGE" /> በመተርጎም ላይ...</translation>
+<translation id="8647750283161643317">ሁሉንም ወደ ነባሪ ዳግም አስጀምር</translation>
<translation id="8713130696108419660">መጥፎ የአስጀማሪ ፊርማ</translation>
<translation id="8725066075913043281">እንደገና ይሞክሩ</translation>
+<translation id="8738058698779197622">ደህንነቱ የተጠበቀ ግንኙነት ለመመስረት፣ የእርስዎ ሰዓት በትክክል መቀናበር ያስፈልገዋል። ይህን የሆነበት ምክንያት የድር ጣቢያዎች ራሳቸውን ለማሳወቅ የሚጠቀሙባቸው የምስክር ወረቀቶች የሚሰሩት ለተወሰኑ ክፍለ ጊዜያቶች ብቻ ስለሆነ ነው። የእርስዎ መሣሪያ ሰዓት ልክ እንዳለመሆኑ መጠን Chromium እነዚህን ምስክር ወረቀቶች ሊያረጋግጣቸው አይችልም።</translation>
<translation id="8790007591277257123">&amp;ሰርዝን ድገም</translation>
<translation id="8804164990146287819">የግላዊነት መመሪያ</translation>
+<translation id="8820817407110198400">ዕልባቶች</translation>
<translation id="8824019021993735287">Chrome የእርስዎን ካርድ በዚህ ጊዜ ላይ ለማረጋገጥ አልቻለም። እባክዎ ቆይተው እንደገና ይሞክሩ።</translation>
<translation id="8834246243508017242">እውቂያዎችን በመጠቀም የራስ ሰር መሙላትን አንቃ…</translation>
<translation id="883848425547221593">ሌላ እልባቶች</translation>
+<translation id="884923133447025588">ምንም የመሻሪያ ዘዴ አልተገኘም።</translation>
<translation id="8866481888320382733">የመምሪያ ቅንብሮችን መተንተን ላይ ስህተት</translation>
<translation id="8876793034577346603">የአውታረ መረብ ውቅር ሊተነተን አልቻለም።</translation>
<translation id="8891727572606052622">ልክ ያልሆነ የተኪ ሁነታ።</translation>
-<translation id="8940229512486821554">የ<ph name="EXTENSION_NAME"/> ትዕዛዝ ያሂዱ፦ <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">ይቅርታ፣ ይህ ሙከራ ለመሣሪያ ስርዓትዎ አይገኝም።</translation>
+<translation id="8903921497873541725">አጉላ</translation>
+<translation id="8932102934695377596">የእርስዎ ሰዓት ወደ ኋላ ቀርቷል</translation>
+<translation id="8940229512486821554">የ<ph name="EXTENSION_NAME" /> ትዕዛዝ ያሂዱ፦ <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">የአገልጋይ እውቅና ማረጋገጫ ጊዜው አልፎበታል።</translation>
<translation id="8988760548304185580">የጊዜ ማብቂያ ቀን እና በካርድዎ ጀርባ ላይ ያለው ባለ3 አኃዝ CVCን ያስገቡ</translation>
-<translation id="9020542370529661692">ይህ ገጽ ወደ <ph name="TARGET_LANGUAGE"/> ተተርጉሟል</translation>
+<translation id="901974403500617787">በመላው ስርዓት ላይ የሚተገበሩ ጥቆማዎች በባለቤቱ ብቻ ነው ሊዋቀሩ የሚችሉት፦ <ph name="OWNER_EMAIL" />።</translation>
+<translation id="9020542370529661692">ይህ ገጽ ወደ <ph name="TARGET_LANGUAGE" /> ተተርጉሟል</translation>
+<translation id="9049981332609050619"><ph name="DOMAIN" />ን ለመድረስ ሞክረው ነበር፣ ግን አገልጋዩ ልክ ያልሆነ የእውቅና ማረጋገጫ ነው ያሳየው።</translation>
<translation id="9125941078353557812">በካርድዎ ኋላ ላይ ያለውን ባለ3 አኃዝ CVCን ያስገቡ</translation>
<translation id="9137013805542155359">የመጀመሪያውን አሳይ</translation>
<translation id="9148507642005240123">&amp;አርትዕን ቀልብስ</translation>
<translation id="9154176715500758432">በዚሁ ገጽ ላይ ቆይ</translation>
<translation id="9170848237812810038">&amp;ቀልብስ</translation>
+<translation id="917450738466192189">የአገልጋይ እውቅና ማረጋገጫ ልክ ያልኾነ ነው።</translation>
+<translation id="9187827965378254003">አይይ፣ በአሁኑ ጊዜ ምንም የሚገኙ መሞከሪያዎች ያሉ አይመስሉም።</translation>
<translation id="9207861905230894330">ጽሑፍ ማከል አልተቻለም።</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ቅጽን አጽዳ</translation>
+<translation id="988159990683914416">የገንቢዎች ግንባታ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ar.xtb b/chromium/components/strings/components_strings_ar.xtb
index 87bb380a76a..a252a600675 100644
--- a/chromium/components/strings/components_strings_ar.xtb
+++ b/chromium/components/strings/components_strings_ar.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ar">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ar">
+<translation id="1032854598605920125">تدوير في اتجاه عقارب الساعة</translation>
<translation id="1055184225775184556">تراجع عن الإ&amp;ضافة</translation>
<translation id="106701514854093668">الإشارات المرجعية على سطح المكتب</translation>
-<translation id="1103523840287552314">ترجمة اللغة <ph name="LANGUAGE"/> دومًا</translation>
+<translation id="1080116354587839789">ملاءمة مع العرض</translation>
+<translation id="1103523840287552314">ترجمة اللغة <ph name="LANGUAGE" /> دومًا</translation>
<translation id="1113869188872983271">تراجع عن إعادة الت&amp;رتيب</translation>
<translation id="111844081046043029">هل تريد بالتأكيد مغادرة هذه الصفحة؟</translation>
<translation id="112840717907525620">ذاكرة التخزين المؤقت للسياسة بحالة جيدة</translation>
<translation id="1132774398110320017">‏إعدادات الملء التلقائي في Chrome...</translation>
-<translation id="1152921474424827756">الدخول إلى <ph name="BEGIN_LINK"/>النسخة المخزنة مؤقتًا<ph name="END_LINK"/> من <ph name="URL"/></translation>
+<translation id="1150979032973867961">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان غير موثقة من خلال نظام تشغيل الكمبيوتر. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض الاتصال.</translation>
+<translation id="1152921474424827756">الدخول إلى <ph name="BEGIN_LINK" />النسخة المخزنة مؤقتًا<ph name="END_LINK" /> من <ph name="URL" /></translation>
+<translation id="121201262018556460">لقد حاولت الوصول إلى <ph name="DOMAIN" />، ولكن الخادم قدّم شهادة تحتوي على مفتاح ضعيف. ربما قام أحد المهاجمين باختراق المفتاح الخاص، ولا يكون الخادم هو الخادم الذي تتوقعه (قد تكون على اتصال بأحد المهاجمين).</translation>
<translation id="1227224963052638717">سياسة غير معروفة.</translation>
<translation id="1227633850867390598">إخفاء القيمة</translation>
<translation id="1228893227497259893">معرف الكيان خاطئ</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">نطاق التسجيل:</translation>
<translation id="1344588688991793829">‏إعدادات الملء التلقائي في Chromium...</translation>
<translation id="1426410128494586442">نعم</translation>
+<translation id="1430915738399379752">طباعة</translation>
<translation id="1455235771979731432">حدثت مشكلة أثناء التحقق من بطاقتك. تحقق من اتصالك بالإنترنت وأعد المحاولة.</translation>
<translation id="1491151370853475546">إعادة تحميل هذه الصفحة</translation>
<translation id="1549470594296187301">‏يجب تمكين JavaScript لاستخدام هذه الميزة.</translation>
-<translation id="1639239467298939599">جارٍ التحميل.</translation>
<translation id="1640180200866533862">سياسات المستخدم</translation>
<translation id="1644184664548287040">تهيئة الشبكة غير صالحة ويتعذر استيرادها.</translation>
-<translation id="1693754753824026215">تعرض الصفحة في <ph name="SITE"/>:</translation>
+<translation id="1655462015569774233">{1,plural, =1{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ انتهت صلاحية شهادة أمانه أمس. ربما يكون السبب في ذلك خطأ في التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصفحة.}zero{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ انتهت صلاحية شهادة أمانه منذ # يوم. ربما يكون السبب في ذلك خطأ في التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصفحة.}two{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ انتهت صلاحية شهادة أمانه منذ يومين (#). ربما يكون السبب في ذلك خطأ في التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصفحة.}few{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ انتهت صلاحية شهادة أمانه منذ # أيام. ربما يكون السبب في ذلك خطأ في التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصفحة.}many{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ انتهت صلاحية شهادة أمانه منذ # يومًا. ربما يكون السبب في ذلك خطأ في التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصفحة.}other{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ انتهت صلاحية شهادة أمانه منذ # يوم. ربما يكون السبب في ذلك خطأ في التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصفحة.}}</translation>
+<translation id="168841957122794586">تحتوي شهادة الخادم على مفتاح تشفير ضعيف.</translation>
+<translation id="1693754753824026215">تعرض الصفحة في <ph name="SITE" />:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان غير موثوقة من خلال نظام تشغيل جهازك. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض الاتصال.</translation>
<translation id="1821930232296380041">طلب غير صالح، أو معلمات طلب غير صالحة</translation>
-<translation id="1853748787962613237">أخفق عرض المقالة.</translation>
<translation id="1871208020102129563">‏تم تعيين الخادم الوكيل لاستخدام الخوادم الوكيلة الثابتة وليس عنوان URL لنص برمجي pac.</translation>
-<translation id="1875753206475436906">نوع الموجّه: <ph name="HEURISTIC_TYPE"/>
- نوع الخادم: <ph name="SERVER_TYPE"/>
- توقيع الحقل: <ph name="FIELD_SIGNATURE"/>
- توقيع النموذج: <ph name="FORM_SIGNATURE"/>
- معرِّف التجربة: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">الانتقال إلى <ph name="LINK"/></translation>
-<translation id="1962204205936693436">إشارات <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">الانتقال إلى <ph name="LINK" /></translation>
+<translation id="1962204205936693436">إشارات <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">خطأ أثناء التسلسل</translation>
+<translation id="1974060860693918893">إعدادات متقدمة</translation>
<translation id="2025186561304664664">تم تعيين الخادم الوكيل على التهيئة التلقائية.</translation>
<translation id="2025623846716345241">تأكيد إعادة التحميل</translation>
-<translation id="2030481566774242610">هل تقصد <ph name="LINK"/>؟</translation>
+<translation id="2030481566774242610">هل تقصد <ph name="LINK" />؟</translation>
<translation id="2053553514270667976">الرمز البريدي</translation>
<translation id="20817612488360358">تم تعيين إعدادات الخادم الوكيل ليتم استخدامها وتم أيضًا تحديد تهيئة صريحة للخادم الوكيل.</translation>
<translation id="2094505752054353250">النطاق غير متطابق</translation>
<translation id="2096368010154057602">الإدارة</translation>
<translation id="2113977810652731515">البطاقة</translation>
-<translation id="2114841414352855701">تم تجاهلها نظرًا لتجاوزها بواسطة <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">تم تجاهلها نظرًا لتجاوزها بواسطة <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">الإشارات المرجعية على الجوال</translation>
+<translation id="2171101176734966184">لقد حاولت الوصول إلى <ph name="DOMAIN" />، ولكن قدَّم الخادم شهادة موقّعة باستخدام خوارزمية توقيع ضعيفة، مما يعني أن بيانات اعتماد الأمان التي قدمها الخادم من المحتمل أنه تم تزييفها، وأن الخادم قد لا يكون هو الخادم الذي تتوقعه (قد تكون على اتصال بأحد المهاجمين).</translation>
<translation id="2181821976797666341">السياسات</translation>
<translation id="2212735316055980242">تعذر العثور على السياسة</translation>
<translation id="2213606439339815911">جارٍ جلب الإدخالات...</translation>
<translation id="225207911366869382">تم تجاهل القيمة لهذه السياسة.</translation>
<translation id="2262243747453050782">‏خطأ HTTP</translation>
-<translation id="2270192940992995399">أخفق العثور على المقالة.</translation>
-<translation id="2328300916057834155">تم تجاهل الإشارة المرجعية غير الصالحة في الفهرس <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">التجارب غير المتاحة</translation>
+<translation id="229702904922032456">انتهت صلاحية الشهادة الأساسية أو المتوسطة.</translation>
+<translation id="2328300916057834155">تم تجاهل الإشارة المرجعية غير الصالحة في الفهرس <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">الإشارات الأخرى</translation>
<translation id="2359808026110333948">المتابعة</translation>
<translation id="2367567093518048410">المستوى</translation>
+<translation id="2384307209577226199">السياسة افتراضية في المؤسسة ويمكن إلغاؤها</translation>
+<translation id="2386255080630008482">تم إبطال شهادة الخادم.</translation>
<translation id="2392959068659972793">عرض السياسات التي لم يتم تعيين قيم لها</translation>
<translation id="2396249848217231973">تراجع عن الحذ&amp;ف</translation>
+<translation id="2413528052993050574">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان ربما تم إلغاء صلاحيتها. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض اتصالك.</translation>
<translation id="2455981314101692989">عطلت صفحة الويب هذه الملء التلقائي لهذا النموذج.</translation>
<translation id="2479410451996844060">‏عنوان URL للبحث غير صالح.</translation>
+<translation id="2491120439723279231">تحتوي شهادة الخادم على أخطاء.</translation>
<translation id="2495083838625180221">‏محلل JSON اللغوي</translation>
<translation id="2498091847651709837">فحص بطاقة جديدة</translation>
<translation id="2556876185419854533">تراجع عن ا&amp;لتحرير</translation>
-<translation id="2581221116934462656">هل تريد أن يعرض <ph name="PRODUCT_NAME"/> ترجمة صفحات <ph name="LANGUAGE_NAME"/> من هذا الموقع في المرة القادمة؟</translation>
+<translation id="2581221116934462656">هل تريد أن يعرض <ph name="PRODUCT_NAME" /> ترجمة صفحات <ph name="LANGUAGE_NAME" /> من هذا الموقع في المرة القادمة؟</translation>
<translation id="2587841377698384444">رقم تعريف واجهة برمجة التطبيقات الدليل:</translation>
<translation id="2597378329261239068">هذا المستند محمي بكلمة المرور. الرجاء إدخال كلمة مرور.</translation>
+<translation id="2625385379895617796">توقيت ساعتك متقدم عن الوقت الحالي</translation>
<translation id="2639739919103226564">الحالة:</translation>
+<translation id="2653659639078652383">إرسال</translation>
<translation id="2704283930420550640">القيمة لا تطابق التنسيق.</translation>
<translation id="2721148159707890343">تم إرسال الطلب بنجاح</translation>
+<translation id="2728127805433021124">شهادة الخادم موقّعة باستخدام خوارزمية توقيع ضعيفة.</translation>
<translation id="2774256287122201187">يمكنك المتابعة. إذا تابعت إلى الصفحة، فلن يظهر هذا التحذير مرة أخرى لمدة خمس دقائق.</translation>
<translation id="277499241957683684">سجِلّ الجهاز مفقود</translation>
<translation id="2835170189407361413">محو النموذج</translation>
-<translation id="2855922900409897335">تحقق من <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">تحقق من <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان منتهية الصلاحية. وربما يكون سبب ذلك خطأ في التهيئة أو مهاجمًا يعترض الاتصال. تم تعيين ساعة الكمبيوتر حاليًا على <ph name="CURRENT_TIME" />. هل تبدو الساعة صحيحة؟ إذا لم تكن كذلك، يجب عليك تصحيح ساعة النظام، ثم تحديث هذه الصفحة.</translation>
+<translation id="2922350208395188000">لا يمكن التحقق من شهادة الخادم.</translation>
+<translation id="2941952326391522266">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان من <ph name="DOMAIN2" />. وربما سبب ذلك خطأ في التكوين أو مهاجمًا يعترض اتصالك.</translation>
<translation id="2958431318199492670">‏لا تتوافق تهيئة الشبكة مع معيار ONC. قد لا يتم استيراد بعض أجزاء التهيئة.</translation>
<translation id="2972581237482394796">إعا&amp;دة</translation>
-<translation id="3010559122411665027">إدخال القائمة &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">إدخال القائمة "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">نوع السياسة غير صحيح</translation>
<translation id="3105172416063519923">رقم تعريف الأصل:</translation>
<translation id="3145945101586104090">أخفق فك تشفير الاستجابة</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">جزيرة</translation>
<translation id="3219579145727097045">‏أدخل تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) المكوّن من أربعة أرقام من الجزء الأمامي من بطاقتك.</translation>
-<translation id="3228969707346345236">أخفقت الترجمة لأن الصفحة باللغة <ph name="LANGUAGE"/> فعلاً.</translation>
+<translation id="3225919329040284222">قدم الخادم شهادة لا تتطابق مع التوقعات المضمّنة. تم تضمين هذه التوقعات للحصول على مواقع ويب موثوقة وآمنة جدًا لتوفير الحماية لك.</translation>
+<translation id="3228969707346345236">أخفقت الترجمة لأن الصفحة باللغة <ph name="LANGUAGE" /> فعلاً.</translation>
<translation id="3270847123878663523">تراجع عن إعادة الت&amp;رتيب</translation>
+<translation id="3286538390144397061">إعادة التشغيل الآن</translation>
<translation id="333371639341676808">منع هذه الصفحة من إنشاء مربّعات حوار إضافية.</translation>
-<translation id="3369366829301677151">تحديث <ph name="CREDIT_CARD"/> والتحقق منها</translation>
+<translation id="3340978935015468852">الإعدادات</translation>
+<translation id="3369192424181595722">خطأ في الساعة</translation>
+<translation id="3369366829301677151">تحديث <ph name="CREDIT_CARD" /> والتحقق منها</translation>
<translation id="337363190475750230">تم إلغاء التوفير</translation>
<translation id="3377188786107721145">خطأ في تحليل السياسة</translation>
<translation id="3380365263193509176">خطأ غير معروف</translation>
<translation id="3380864720620200369">معرِّف العميل:</translation>
<translation id="3427342743765426898">إعادة الت&amp;حرير</translation>
+<translation id="3435896845095436175">تمكين الإضافات</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">الفاصل الزمني للجلب:</translation>
+<translation id="3462200631372590220">الإخفاء (خيار متقدم)</translation>
+<translation id="3528171143076753409">شهادة الخادم غير موثوق فيها.</translation>
<translation id="3542684924769048008">استخدام كلمة مرور لـ:</translation>
<translation id="3583757800736429874">إ&amp;عادة النقل</translation>
<translation id="3623476034248543066">عرض القيمة</translation>
+<translation id="3648607100222897006">ربما تتغير أو تتعطل أو تختفي هذه الميزات التجريبية في أي وقت. ولا نعطي أي ضمانات حيال ما يمكن حدوثه إذا شغلت إحدى هذه الميزات التجريبية، وقد يتعطل المتصفح بشكل مفاجئ. وبشكل جدي، قد يحذف المتصفح جميع بياناتك، أو قد تتعرض خصوصيتك وأمانك للاختراق بطرق غير متوقعة. أي ميزات تجريبية تمكّنها سيتم تمكينها لجميع مستخدمي هذا المتصفح. الرجاء المتابعة بحذر.</translation>
<translation id="3650584904733503804">تم التحقق بنجاح</translation>
<translation id="370665806235115550">تحميل...</translation>
<translation id="3712624925041724820">التراخيص مستنفذة</translation>
<translation id="3739623965217189342">الرابط الذي نسخته</translation>
<translation id="375403751935624634">أخفقت الترجمة بسبب حدوث خطأ في الخادم.</translation>
<translation id="385051799172605136">الرجوع إلى الوراء</translation>
+<translation id="3858027520442213535">تحديث التاريخ والوقت</translation>
<translation id="3884278016824448484">معرف جهاز متضارب</translation>
<translation id="3885155851504623709">دائرة</translation>
<translation id="3934680773876859118">‏إخفاق تحميل مستند PDF</translation>
<translation id="3963721102035795474">وضع القارئ</translation>
<translation id="4030383055268325496">تراجع عن الإ&amp;ضافة</translation>
-<translation id="4058922952496707368">المفتاح &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">تحذير</translation>
+<translation id="4058922952496707368">المفتاح "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">‏تم تعيين تهيئة الخادم الوكيل لاستخدام عنوان URL نص برمجي ‎.pac وليس الخوادم الوكيلة الثابتة.</translation>
<translation id="409504436206021213">إلغاء إعادة التحميل</translation>
<translation id="4103249731201008433">الرقم التسلسلي للجهاز غير صالح</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">توقيع غير صالح</translation>
<translation id="4269787794583293679">(اسم المستخدم غير موجود)</translation>
<translation id="4300246636397505754">اقتراحات الآباء</translation>
-<translation id="4372948949327679948">القيمة <ph name="VALUE_TYPE"/> المتوقعة.</translation>
+<translation id="4325863107915753736">أخفق العثور على المقالة</translation>
+<translation id="4372948949327679948">القيمة <ph name="VALUE_TYPE" /> المتوقعة.</translation>
+<translation id="4377125064752653719">لقد حاولت الوصول إلى <ph name="DOMAIN" />، ولكن جهة إصدار الشهادة التي قدمها الخادم قد أبطلت الشهادة. وهذا يعني أن بيانات اعتماد الأمان التي قدمها الخادم يجب عدم الوثوق بها مطلقًا. فقد تكون على اتصال بأحد المهاجمين.</translation>
+<translation id="4394049700291259645">تعطيل</translation>
+<translation id="4424024547088906515">‏هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان غير موثوقة من قبل Chrome. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض الاتصال.</translation>
<translation id="443673843213245140">تم تعطيل استخدام الخادم الوكيل ولكن تم تحديد تهيئة صريحة للخادم الوكيل.</translation>
-<translation id="4506176782989081258">خطأ في عملية التحقق: <ph name="VALIDATION_ERROR"/>.</translation>
+<translation id="4506176782989081258">خطأ في عملية التحقق: <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4587425331216688090">‏هل تريد إزالة العنوان من Chrome؟</translation>
<translation id="4594403342090139922">تراجع عن الحذ&amp;ف</translation>
<translation id="4607653538520819196">لا يمكن إنشاء خادم وكيل لهذه الصفحة من خلال توفير البيانات.</translation>
<translation id="4668929960204016307">،</translation>
+<translation id="467662567472608290">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان تحتوي على أخطاء. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض اتصالك.</translation>
<translation id="4726672564094551039">إعادة تحميل السياسات</translation>
+<translation id="4728558894243024398">النظام الأساسي</translation>
+<translation id="4771973620359291008">حدث خطأ غير محدّد.</translation>
<translation id="4800132727771399293">‏تحقق من تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) وأعد المحاولة مرة أخرى.</translation>
<translation id="4813512666221746211">حدث خطأ في الشبكة</translation>
+<translation id="4816492930507672669">احتواء ضمن الصفحة</translation>
<translation id="4850886885716139402">عرض</translation>
-<translation id="4923417429809017348">تمت ترجمة هذه الصفحة من لغة غير معروفة إلى اللغة <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">تمت ترجمة هذه الصفحة من لغة غير معروفة إلى اللغة <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">يجب تحديدها.</translation>
<translation id="4968547170521245791">لا يمكن إنشاء خادم وكيل</translation>
-<translation id="498957508165411911">هل تريد الترجمة من <ph name="ORIGINAL_LANGUAGE"/> إلى <ph name="TARGET_LANGUAGE"/>؟</translation>
+<translation id="498957508165411911">هل تريد الترجمة من <ph name="ORIGINAL_LANGUAGE" /> إلى <ph name="TARGET_LANGUAGE" />؟</translation>
<translation id="5019198164206649151">التخزين المساعد في حالة سيئة</translation>
<translation id="5031870354684148875">‏معلومات عن الترجمة من Google</translation>
+<translation id="5045550434625856497">كلمة مرور غير صحيحة</translation>
+<translation id="5087286274860437796">شهادة الخادم ليست صالحة حاليًا.</translation>
<translation id="5089810972385038852">بلد/دولة</translation>
+<translation id="5094747076828555589">‏هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان غير موثوقة من قبل Chromium. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض الاتصال.</translation>
<translation id="5095208057601539847">الإقليم</translation>
<translation id="5145883236150621069">يوجد رمز خطأ في استجابة السياسة</translation>
<translation id="5172758083709347301">الجهاز</translation>
-<translation id="5179510805599951267">هل الصفحة ليست باللغة <ph name="ORIGINAL_LANGUAGE"/>؟ الإبلاغ عن هذا الخطأ</translation>
+<translation id="5179510805599951267">هل الصفحة ليست باللغة <ph name="ORIGINAL_LANGUAGE" />؟ الإبلاغ عن هذا الخطأ</translation>
<translation id="5190835502935405962">شريط الإشارات</translation>
+<translation id="5199729219167945352">التجارب</translation>
+<translation id="5251803541071282808">السحاب</translation>
<translation id="5295309862264981122">تأكيد التصفح</translation>
<translation id="5299298092464848405">خطأ في تحليل السياسة</translation>
+<translation id="5316812925700871227">تدوير عكس اتجاه عقارب الساعة</translation>
<translation id="5317780077021120954">حفظ</translation>
<translation id="536296301121032821">أخفق تخزين إعدادات السياسة</translation>
-<translation id="5439770059721715174">حدث خطأ في مصادقة المخطط على &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">لم يتمكن هذا الخادم من إثبات أنه <ph name="DOMAIN" />؛ بل إن شهادة الأمان الخاصة به غير صالحة حاليًا. وربما يكون السبب في ذلك وجود خطأ في التكوين أو اعترض أحد المهاجمين للاتصال.</translation>
+<translation id="5439770059721715174">حدث خطأ في مصادقة المخطط على "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">الطابع الزمني للسياسة سيئ</translation>
<translation id="5470861586879999274">إعادة الت&amp;حرير</translation>
<translation id="5509780412636533143">الإشارات المرجعية المُدارة</translation>
<translation id="5523118979700054094">اسم السياسة</translation>
<translation id="552553974213252141">هل تم استخراج النص بشكل صحيح؟</translation>
<translation id="5540224163453853">تعذر العثور على المقالة المطلوبة</translation>
+<translation id="5556459405103347317">إعادة تحميل</translation>
<translation id="5565735124758917034">نشط</translation>
<translation id="560412284261940334">الإدارة غير متوفرة</translation>
<translation id="5629630648637658800">أخفق تحميل إعدادات السياسة</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">المستخدم الحالي</translation>
<translation id="5813119285467412249">إعا&amp;دة الإضافة</translation>
<translation id="5872918882028971132">اقتراحات الآباء</translation>
-<translation id="587701087903783706">غلق عرض متوافق مع الجوّال</translation>
<translation id="59107663811261420">‏هذا النوع من البطاقات غير متوافق مع Google Payments لهذا التاجر. يُرجى تحديد بطاقة أخرى.</translation>
+<translation id="5975083100439434680">تصغير</translation>
<translation id="5989320800837274978">‏لم يتم تحديد أي من الخوادم الوكيلة الثابتة ولا عنوان URL للنص البرمجي pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">إغلاق</translation>
+<translation id="6060685159320643512">احذر، هذه التجارب غير مضمونة النتائج</translation>
+<translation id="6151417162996330722">فترة صلاحية شهادة الخادم طويلة جدًا.</translation>
<translation id="6154808779448689242">لا يتطابق الرمز المميز لسياسة الإرجاع مع الرمز المميز الحالي</translation>
<translation id="6165508094623778733">مزيد من المعلومات</translation>
<translation id="6259156558325130047">إعادة إ&amp;جراء الترتيب</translation>
-<translation id="6263376278284652872">إشعارات <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">إشعارات <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">الرمز البريدي</translation>
<translation id="6337534724793800597">تصفية السياسات بحسب الاسم</translation>
+<translation id="6387478394221739770">‏إذا كنت مهتمًا بميزات Google الجديدة والرائعة، فيُمكنك تجربة القناة التجريبية على chrome.com/beta.</translation>
+<translation id="6426993025560594914">جميع التجارب متاحة على النظام الأساسي الذي تستخدمه!</translation>
<translation id="6445051938772793705">البلد</translation>
<translation id="6458467102616083041">تم التجاهل نظرًا لتعطيل البحث الافتراضي بواسطة السياسة.</translation>
<translation id="647261751007945333">سياسات الأجهزة</translation>
<translation id="6512448926095770873">مغادرة هذه الصفحة</translation>
<translation id="6529602333819889595">إعادة الح&amp;ذف</translation>
<translation id="6550675742724504774">خيارات</translation>
-<translation id="6597614308054261376">تحاول الوصول إلى <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. لا يمكن إنشاء خادم وكيل لهذه الصفحة من خلال توفير البيانات في الوقت الحالي.</translation>
-<translation id="6628463337424475685">بحث <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">تحاول الوصول إلى <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. لا يمكن إنشاء خادم وكيل لهذه الصفحة من خلال توفير البيانات في الوقت الحالي.</translation>
+<translation id="6628463337424475685">بحث <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">تم تجاهل هذه السياسة.</translation>
<translation id="6646897916597483132">‏أدخل رمز التحقق من البطاقة (CVC) المكون من أربعة أرقام من الجزء الأمامي من بطاقتك</translation>
+<translation id="674375294223700098">حدث خطأ غير معروف في شهادة الخادم.</translation>
<translation id="6753269504797312559">قيمة السياسة</translation>
<translation id="6831043979455480757">ترجمة</translation>
<translation id="6839929833149231406">المنطقة</translation>
<translation id="6874604403660855544">إعا&amp;دة الإضافة</translation>
<translation id="6891596781022320156">مستوى السياسة غير مدعوم.</translation>
<translation id="6915804003454593391">المستخدم:</translation>
+<translation id="6957887021205513506">يبدو أن شهادة الخادم مزيفة.</translation>
<translation id="6965382102122355670">موافق</translation>
<translation id="6965978654500191972">جهاز</translation>
<translation id="6970216967273061347">المنطقة</translation>
<translation id="6973656660372572881">‏تم تحديد كل من الخوادم الوكيلة الثابتة وعنوان URL للنص البرمجي pac.</translation>
<translation id="6980028882292583085">تنبيه جافا سكريبت</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">لقد حاولت الوصول إلى <ph name="DOMAIN" />، ولكن الخادم قدم شهادة مدة صلاحيتها طويلة جدًا مما يجعلها غير جديرة بالثقة.</translation>
<translation id="7087282848513945231">المقاطعة/الإقليم/المنطقة</translation>
-<translation id="7108649287766967076">أخفقت الترجمة إلى <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="7108649287766967076">أخفقت الترجمة إلى <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="7139724024395191329">الإمارة</translation>
+<translation id="7179921470347911571">إعادة التشغيل الآن</translation>
<translation id="7180611975245234373">تحديث</translation>
<translation id="7182878459783632708">لم يتم تعيين أية سياسات</translation>
-<translation id="7186367841673660872">تمت ترجمة هذه الصفحة من اللغة<ph name="ORIGINAL_LANGUAGE"/>إلى اللغة<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="7186367841673660872">تمت ترجمة هذه الصفحة من اللغة<ph name="ORIGINAL_LANGUAGE" />إلى اللغة<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">البحث في الموقع <ph name="SITE_NAME"/> عن &quot;<ph name="SEARCH_TERMS"/>&quot;</translation>
+<translation id="7208899522964477531">البحث في الموقع <ph name="SITE_NAME" /> عن "<ph name="SEARCH_TERMS" />"</translation>
+<translation id="725866823122871198">تعذر إنشاء اتصال خاص بـ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> نظرًا لأن التاريخ والوقت لجهاز الكمبيوتر (<ph name="DATE_AND_TIME" />) غير صحيحين.</translation>
<translation id="7275334191706090484">الإشارات المرجعية المُدارة</translation>
<translation id="7298195798382681320">موصى بها</translation>
<translation id="7334320624316649418">إعادة إ&amp;جراء الترتيب</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">جافا سكريبت</translation>
<translation id="7537536606612762813">إلزامية</translation>
<translation id="7542995811387359312">تم تعطيل الملء التلقائي لبطاقة الائتمان لأن هذا النموذج لا يستخدم اتصالاً آمنًا.</translation>
-<translation id="7568593326407688803">تتوفر هذه الصفحة باللغة<ph name="ORIGINAL_LANGUAGE"/>فهل تريد ترجمتها؟</translation>
+<translation id="7567204685887185387">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان تم إصدارها عن طريق الاحتيال. وربما يكون سبب ذلك خطأ في التكوين أو مهاجمًا يعترض اتصالك.</translation>
+<translation id="7568593326407688803">تتوفر هذه الصفحة باللغة<ph name="ORIGINAL_LANGUAGE" />فهل تريد ترجمتها؟</translation>
<translation id="7569952961197462199">‏هل تريد إزالة بطاقة الائتمان من Chrome؟</translation>
-<translation id="7600965453749440009">عدم الترجمة مطلقًا من اللغة <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">القيمة خارج النطاق <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">تنتهك شهادة الخادم القيود المفروضة على الاسم.</translation>
+<translation id="7600965453749440009">عدم الترجمة مطلقًا من اللغة <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">القيمة خارج النطاق <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">‏إذا كنت مهتمًا بميزات Google الجديدة والرائعة، فيُمكنك تجربة قناة مطوري البرامج على chrome.com/dev.</translation>
<translation id="7752995774971033316">غير مُدار</translation>
+<translation id="7761701407923456692">‏لا تتطابق شهادة الخادم مع عنوان URL.</translation>
<translation id="777702478322588152">الإدارة الأمنية</translation>
<translation id="7791543448312431591">إضافة</translation>
<translation id="7805768142964895445">الحالة</translation>
<translation id="7813600968533626083">‏هل تريد إزالة اقتراح النموذج من Chrome؟</translation>
<translation id="7887683347370398519">‏تحقق من رمز التحقق من البطاقة (CVC) ثم أعد المحاولة.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">شهادة الخادم ليست صالحة بعد.</translation>
<translation id="7956713633345437162">الإشارات المرجعية على الجوال</translation>
<translation id="7961015016161918242">مطلقًا</translation>
<translation id="7977590112176369853">&lt;أدخل طلب البحث&gt;</translation>
-<translation id="7983301409776629893">الترجمة من اللغة <ph name="ORIGINAL_LANGUAGE"/> إلى اللغة <ph name="TARGET_LANGUAGE"/> دومًا</translation>
+<translation id="7983301409776629893">الترجمة من اللغة <ph name="ORIGINAL_LANGUAGE" /> إلى اللغة <ph name="TARGET_LANGUAGE" /> دومًا</translation>
<translation id="7988324688042446538">الإشارات المرجعية على سطح المكتب</translation>
<translation id="7995512525968007366">غير محدد</translation>
-<translation id="8034522405403831421">هذه الصفحة باللغة <ph name="SOURCE_LANGUAGE"/>. هل تريد ترجمتها إلى اللغة <ph name="TARGET_LANGUAGE"/>؟</translation>
+<translation id="8003882219468422867">السياسة مفروضة في المؤسسة ولا يمكن إلغاؤها</translation>
+<translation id="8034522405403831421">هذه الصفحة باللغة <ph name="SOURCE_LANGUAGE" />. هل تريد ترجمتها إلى اللغة <ph name="TARGET_LANGUAGE" />؟</translation>
<translation id="8088680233425245692">أخفق عرض المقالة.</translation>
<translation id="8091372947890762290">التنشيط قيد الانتظار في الخادم</translation>
<translation id="8194797478851900357">تراجع عن ال&amp;نقل</translation>
-<translation id="8201077131113104583">‏عنوان URL لتحديث الإضافة التي تحتوي على رقم التعريف &quot;<ph name="EXTENSION_ID"/>&quot; غير صالح.</translation>
+<translation id="8201077131113104583">‏عنوان URL لتحديث الإضافة التي تحتوي على رقم التعريف "<ph name="EXTENSION_ID" />" غير صالح.</translation>
<translation id="8208216423136871611">عدم الحفظ</translation>
<translation id="8218327578424803826">الموقع الذي تم تعيينه:</translation>
<translation id="8249320324621329438">تاريخ آخر عملية جلب:</translation>
+<translation id="8294431847097064396">المصدر</translation>
<translation id="8308427013383895095">أخفقت الترجمة بسبب حدوث مشكلة في الاتصال بالشبكة.</translation>
<translation id="8311778656528046050">هل تريد بالتأكيد إعادة تحميل هذه الصفحة؟</translation>
<translation id="8349305172487531364">شريط الإشارات</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">تنطبق على</translation>
<translation id="8530504477309582336">‏هذا النوع من البطاقات غير متوافق مع Google Payments. يُرجى تحديد بطاقة مختلفة.</translation>
<translation id="8553075262323480129">أخفقت الترجمة لتعذر تحديد لغة الصفحة.</translation>
-<translation id="8571890674111243710">جارٍ ترجمة الصفحة إلى <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">تعذر إنشاء اتصال خاص بـ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> نظرًا لأن التاريخ والوقت للجهاز (<ph name="DATE_AND_TIME" />) غير صحيحين.</translation>
+<translation id="8571890674111243710">جارٍ ترجمة الصفحة إلى <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">إعادة التعيين على الإعدادات الافتراضية</translation>
<translation id="8713130696108419660">توقيع أولي غير صحيح</translation>
<translation id="8725066075913043281">أعد المحاولة</translation>
+<translation id="8738058698779197622">‏لإنشاء اتصال آمن، فإنك بحاجة إلى ضبط ساعتك بشكل صحيح. وذلك لأن الشهادات التي تستخدمها مواقع الويب لتعريف نفسها تكون صالحة فقط لفترات محددة من الوقت. فإذا كانت ساعة جهازك غير صحيحة، فلن يتمكن Chromium من التحقق من هذه الشهادات.</translation>
<translation id="8790007591277257123">إعادة الح&amp;ذف</translation>
<translation id="8804164990146287819">سياسة الخصوصية</translation>
+<translation id="8820817407110198400">إشارات</translation>
<translation id="8824019021993735287">‏لم يتمكن Chrome من التحقق من بطاقتك في الوقت الحالي.يُرجى إعادة المحاولة في وقت لاحق.</translation>
<translation id="8834246243508017242">تمكين الملء التلقائي باستخدام جهات الاتصال...</translation>
<translation id="883848425547221593">إشارات أخرى</translation>
+<translation id="884923133447025588">لم يتمّ العثور على أي آلبة إبطال.</translation>
<translation id="8866481888320382733">خطأ في إعدادات تحليل السياسة</translation>
<translation id="8876793034577346603">أخفق تحليل تهيئة الشبكة</translation>
<translation id="8891727572606052622">وضع الخادم الوكيل غير صالح.</translation>
-<translation id="8940229512486821554">تشغيل الأمر <ph name="EXTENSION_NAME"/>:<ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">عذرًا، هذه التجربة غير متاحة على نظامك الأساسي.</translation>
+<translation id="8903921497873541725">تكبير</translation>
+<translation id="8932102934695377596">توقيت ساعتك متأخر عن الوقت الحالي</translation>
+<translation id="8940229512486821554">تشغيل الأمر <ph name="EXTENSION_NAME" />:<ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">انتهت صلاحية شهادة الخادم.</translation>
<translation id="8988760548304185580">‏أدخل تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) المكوّن من ثلاثة أرقام من الجزء الخلفي من بطاقتك.</translation>
-<translation id="9020542370529661692">تمت ترجمة هذه الصفحة إلى <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">لا يمكن تعيين العلامات التي تسري عبر النظام إلا من قِبل المالك: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">تمت ترجمة هذه الصفحة إلى <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">لقد حاولت الوصول إلى <ph name="DOMAIN" />, ولكن الخادم قدّم شهادة غير صالحة.</translation>
<translation id="9125941078353557812">‏أدخل رمز التحقق من البطاقة (CVC) المكون من ثلاثة أرقام من الجزء الخلفي من بطاقتك</translation>
<translation id="9137013805542155359">إظهار الصفحة الأصلية</translation>
<translation id="9148507642005240123">تراجع عن ا&amp;لتحرير</translation>
<translation id="9154176715500758432">البقاء في هذه الصفحة</translation>
<translation id="9170848237812810038">&amp;إلغاء</translation>
+<translation id="917450738466192189">شهادة الخادم غير صالحة.</translation>
+<translation id="9187827965378254003">للأسف لا تتوفر أية تجارب في الوقت الحالي.</translation>
<translation id="9207861905230894330">أخفقت إضافة مقالة.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">محو النموذج</translation>
+<translation id="988159990683914416">بنية المطوِّر</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_bg.xtb b/chromium/components/strings/components_strings_bg.xtb
index cef223616ba..b76f981811b 100644
--- a/chromium/components/strings/components_strings_bg.xtb
+++ b/chromium/components/strings/components_strings_bg.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="bg">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="bg">
+<translation id="1032854598605920125">Завъртане по часовниковата стрелка</translation>
<translation id="1055184225775184556">&amp;Отмяна на добавянето</translation>
<translation id="106701514854093668">Настолни отметки</translation>
-<translation id="1103523840287552314">Винаги да се превежда от <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Побиране на ширина</translation>
+<translation id="1103523840287552314">Винаги да се превежда от <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Отмяна на пренареждането</translation>
<translation id="111844081046043029">Наистина ли искате да излезете от тази страница?</translation>
<translation id="112840717907525620">Кешът на правилото е в добро състояние</translation>
<translation id="1132774398110320017">Настройки за Автоматично попълване в Chrome...</translation>
-<translation id="1152921474424827756">Вижте <ph name="BEGIN_LINK"/>кеширано копие<ph name="END_LINK"/> на <ph name="URL"/></translation>
+<translation id="1150979032973867961">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; операционната система на компютъра ви няма доверие на сертификата му за сигурност. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
+<translation id="1152921474424827756">Вижте <ph name="BEGIN_LINK" />кеширано копие<ph name="END_LINK" /> на <ph name="URL" /></translation>
+<translation id="121201262018556460">Направихте опит да се свържете с/ъс <ph name="DOMAIN" />, но сървърът предостави сертификат, съдържащ слаб ключ. Възможно е извършител на атака да е пробил личния ключ и сървърът да не е този, който очаквате (възможно е да сте се свързали с извършител на атака).</translation>
<translation id="1227224963052638717">Неизвестно правило.</translation>
<translation id="1227633850867390598">Скриване на стойността</translation>
<translation id="1228893227497259893">Грешен идентификатор на обект</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Домейн за записване:</translation>
<translation id="1344588688991793829">Настройки за Автоматично попълване в Chromium...</translation>
<translation id="1426410128494586442">Да</translation>
+<translation id="1430915738399379752">Печат</translation>
<translation id="1455235771979731432">При потвърждаването на картата ви възникна проблем. Проверете връзката си с интернет и опитайте отново.</translation>
<translation id="1491151370853475546">Презареждане на тази страница</translation>
<translation id="1549470594296187301">Трябва да активирате JavaScript, за да използвате тази функция.</translation>
-<translation id="1639239467298939599">Зарежда се</translation>
<translation id="1640180200866533862">Правила за потребителите</translation>
<translation id="1644184664548287040">Конфигурацията на мрежата е невалидна и не можа да се импортира.</translation>
-<translation id="1693754753824026215">Страницата на адрес <ph name="SITE"/> показва:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за сигурност е изтекъл вчера. Това може да се дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. Понастоящем часовникът на компютъра ви показва <ph name="CURRENT_DATE" />. Това изглежда ли правилно? Ако не е, трябва да сверите системния часовник и след това да опресните страницата.}other{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за сигурност е изтекъл преди # дни. Това може да се дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. Понастоящем часовникът на компютъра ви показва <ph name="CURRENT_DATE" />. Това изглежда ли правилно? Ако не е, трябва да сверите системния часовник и след това да опресните страницата.}}</translation>
+<translation id="168841957122794586">Сертификатът на сървъра съдържа слаб криптографски ключ.</translation>
+<translation id="1693754753824026215">Страницата на адрес <ph name="SITE" /> показва:</translation>
+<translation id="1706954506755087368">{1,plural, =1{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за сигурност е от утре. Това може да се дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака.}other{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за сигурност е от # дни в бъдещето. Това може да се дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; операционната система на устройството ви няма доверие на сертификата му за сигурност. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="1821930232296380041">Заявката или параметрите й са невалидни</translation>
-<translation id="1853748787962613237">Показването на статията не бе успешно.</translation>
<translation id="1871208020102129563">За прокси сървъра е зададено да използва фиксирани прокси сървъри, а не URL адрес на скрипт във формат .pac.</translation>
-<translation id="1875753206475436906">евристичен тип: <ph name="HEURISTIC_TYPE"/>
-тип сървър: <ph name="SERVER_TYPE"/>
-подпис в полето: <ph name="FIELD_SIGNATURE"/>
-подпис във формуляра: <ph name="FORM_SIGNATURE"/>
-идентификатор на експеримента: „<ph name="EXPERIMENT_ID"/>“</translation>
-<translation id="194030505837763158">Към <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Отметки от <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Към <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Отметки от <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Грешка при сериализирането</translation>
+<translation id="1974060860693918893">Разширени</translation>
<translation id="2025186561304664664">За прокси сървъра е зададена автоматична конфигурация.</translation>
<translation id="2025623846716345241">Потвърждаване на презареждането</translation>
-<translation id="2030481566774242610">Може би имахте предвид <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Може би имахте предвид <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Пощенски код</translation>
<translation id="20817612488360358">За използване са зададени системни настройки за прокси сървъра, но е посочена и изрична конфигурация.</translation>
<translation id="2094505752054353250">Несъответствие в домейна</translation>
<translation id="2096368010154057602">Департамент</translation>
<translation id="2113977810652731515">Карта</translation>
-<translation id="2114841414352855701">Бе пренебрегнато, защото бе отменено от <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Бе пренебрегнато, защото бе отменено от <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Клиент с директно изпълнение</translation>
<translation id="213826338245044447">Мобилни отметки</translation>
+<translation id="2171101176734966184">Направихте опит да се свържете с/ъс <ph name="DOMAIN" />, но сървърът предостави сертификат, подписан със слаб алгоритъм. Това означава, че идентификационните данни за сигурност от сървъра може да са фалшифицирани и той да не е този, който очаквате (възможно е да сте се свързали с извършител на атака).</translation>
<translation id="2181821976797666341">Правила</translation>
<translation id="2212735316055980242">Правилото не е намерено</translation>
<translation id="2213606439339815911">Записите се извличат...</translation>
<translation id="225207911366869382">Стойността е оттеглена за това правило.</translation>
<translation id="2262243747453050782">HTTP грешка</translation>
-<translation id="2270192940992995399">Намирането на статията не бе успешно.</translation>
-<translation id="2328300916057834155">Пренебрегната бе невалидна отметка в индекс <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Експерименти, които не са налице</translation>
+<translation id="229702904922032456">Валидността на основен или междинен сертификат е изтекла.</translation>
+<translation id="2328300916057834155">Пренебрегната бе невалидна отметка в индекс <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Други отметки</translation>
<translation id="2359808026110333948">Напред</translation>
<translation id="2367567093518048410">Ниво</translation>
+<translation id="2384307209577226199">Зададено по подразбиране в корпоративна среда</translation>
+<translation id="2386255080630008482">Сертификатът на сървъра е анулиран.</translation>
<translation id="2392959068659972793">Да се показват правилата без зададена стойност</translation>
<translation id="2396249848217231973">&amp;Отмяна на изтриването</translation>
+<translation id="2413528052993050574">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; възможно е сертификатът му за сигурност да е оттеглен. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="2455981314101692989">Тази уеб страница е деактивирала автоматичното попълване за този формуляр.</translation>
<translation id="2479410451996844060">Невалиден URL адрес за търсене.</translation>
+<translation id="2491120439723279231">Сертификатът на сървъра съдържа грешки.</translation>
<translation id="2495083838625180221">Синтактичен анализ на JSON</translation>
<translation id="2498091847651709837">Сканиране на нова карта</translation>
<translation id="2556876185419854533">&amp;Отмяна на редактирането</translation>
-<translation id="2581221116934462656">Искате ли следващия път <ph name="PRODUCT_NAME"/> да предложи превод на написаните на <ph name="LANGUAGE_NAME"/> страници от този сайт?</translation>
+<translation id="2581221116934462656">Искате ли следващия път <ph name="PRODUCT_NAME" /> да предложи превод на написаните на <ph name="LANGUAGE_NAME" /> страници от този сайт?</translation>
<translation id="2587841377698384444">ID на API за директории:</translation>
<translation id="2597378329261239068">Този документ е защитен с парола. Моля, въведете я.</translation>
+<translation id="2625385379895617796">Часовникът ви е напред</translation>
<translation id="2639739919103226564">Състояние:</translation>
+<translation id="2653659639078652383">Изпращане</translation>
<translation id="2704283930420550640">Стойността не съответства на формата.</translation>
<translation id="2721148159707890343">Заявката е успешна</translation>
+<translation id="2728127805433021124">Сертификатът на сървъра е подписан със слаб алгоритъм.</translation>
<translation id="2774256287122201187">Може да продължите към страницата. Ако го направите, това предупреждение няма да се показва пет минути.</translation>
<translation id="277499241957683684">Липсващ запис за устройството</translation>
<translation id="2835170189407361413">Изчистване на формуляра</translation>
-<translation id="2855922900409897335">Потвърждаване на <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Потвърждаване на <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Сървърът не можа да докаже, че е <ph name="DOMAIN" /> – сертификатът му за сигурност е изтекъл. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от извършител на атака. Понастоящем часовникът на компютъра ви показва <ph name="CURRENT_TIME" />. Това правилно ли е? Ако не е, трябва да сверите системния си часовник и след това да опресните страницата.</translation>
+<translation id="2922350208395188000">Сертификатът на сървъра не може да бъде проверен.</translation>
+<translation id="2941952326391522266">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; сертификатът му за сигурност е от <ph name="DOMAIN2" />. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="2958431318199492670">Конфигурацията на мрежата не спазва стандарта на ONC. Възможно е части от нея да не са импортирани.</translation>
<translation id="2972581237482394796">&amp;Възстановяване</translation>
-<translation id="3010559122411665027">Списъчен запис „<ph name="ENTRY_INDEX"/>“: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Списъчен запис „<ph name="ENTRY_INDEX" />“: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Грешен тип на правилото</translation>
<translation id="3105172416063519923">ID на актива:</translation>
<translation id="3145945101586104090">Декодирането на отговора не бе успешно</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Остров</translation>
<translation id="3219579145727097045">Въведете датата на валидност и четирицифрения код за проверка от лицевата страна на картата си</translation>
-<translation id="3228969707346345236">Преводът не бе успешен, защото страницата вече е на <ph name="LANGUAGE"/>.</translation>
+<translation id="3225919329040284222">Сървърът предостави сертификат, който не съответства на вградените очаквания. Те са включени за определени уебсайтове с голяма степен на сигурност, за да ви предпазим.</translation>
+<translation id="3228969707346345236">Преводът не бе успешен, защото страницата вече е на <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Отмяна на пренареждането</translation>
+<translation id="3286538390144397061">Рестартиране сега</translation>
<translation id="333371639341676808">Да не се показват допълнителни диалогови прозорци от тази страница.</translation>
-<translation id="3369366829301677151">Актуализиране и потвърждаване на <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">настройки</translation>
+<translation id="3369192424181595722">Грешка в часовника</translation>
+<translation id="3369366829301677151">Актуализиране и потвърждаване на <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Обезпечаването е отменено</translation>
<translation id="3377188786107721145">Грешка при синтактичния анализ на правилото</translation>
<translation id="3380365263193509176">Неизвестна грешка</translation>
<translation id="3380864720620200369">Идент. № на клиентската програма:</translation>
<translation id="3427342743765426898">&amp;Възстановяване на редактирането</translation>
+<translation id="3435896845095436175">Активиране</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Интервал на извличане:</translation>
+<translation id="3462200631372590220">Скриване на подробностите</translation>
+<translation id="3528171143076753409">Сертификатът на сървъра не е надежден.</translation>
<translation id="3542684924769048008">Използване на паролата за:</translation>
<translation id="3583757800736429874">&amp;Възстановяване на преместването</translation>
<translation id="3623476034248543066">Показване на стойността</translation>
+<translation id="3648607100222897006">Тези експериментални функции може да се променят, повредят или изчезнат по всяко време. Не даваме абсолютно никаква гаранция какво може да се случи, ако включите някоя от тях. Възможно е дори браузърът ви спонтанно да се самозапали. Шегата настрани, браузърът ви може да изтрие всичките ви данни или сигурността и поверителността ви може да бъдат компрометирани по неочаквани начини. Активираните от вас експерименти ще работят за всички потребители на този браузър. Моля, действайте внимателно.</translation>
<translation id="3650584904733503804">Потвърждаването е успешно</translation>
<translation id="370665806235115550">Зарежда се...</translation>
<translation id="3712624925041724820">Лицензите са изчерпани</translation>
<translation id="3739623965217189342">Копирана от вас връзка</translation>
<translation id="375403751935624634">Преводът не бе успешен поради грешка в сървъра.</translation>
<translation id="385051799172605136">Назад</translation>
+<translation id="3858027520442213535">Актуализиране на датата и часа</translation>
<translation id="3884278016824448484">Идентификационният номер на устройството е несъвместим</translation>
<translation id="3885155851504623709">Община</translation>
<translation id="3934680773876859118">PDF документът не успя да се зареди</translation>
<translation id="3963721102035795474">Режим за четене</translation>
<translation id="4030383055268325496">&amp;Отмяна на добавянето</translation>
-<translation id="4058922952496707368">Ключ „<ph name="SUBKEY"/>“: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ПРЕДУПРЕЖДЕНИЕ</translation>
+<translation id="4058922952496707368">Ключ „<ph name="SUBKEY" />“: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">За конфигурацията на прокси сървъра е зададено да използва URL адрес на скрипт във формат .pac, а не фиксирани прокси сървъри.</translation>
<translation id="409504436206021213">Без презареждане</translation>
<translation id="4103249731201008433">Серийният номер на устройството е невалиден</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Невалиден подпис</translation>
<translation id="4269787794583293679">(Няма потребителско име)</translation>
<translation id="4300246636397505754">Основни предложения</translation>
-<translation id="4372948949327679948">Очаквана е стойност от тип <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Намирането на статията не бе успешно</translation>
+<translation id="4372948949327679948">Очаквана е стойност от тип <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Направихте опит да се свържете с/ъс <ph name="DOMAIN" />, но сървърът предoстави сертификат, анулиран от издателя си. Това означава, че в никакъв случай не трябва да се доверявате на представените от сървъра идентификационни данни за сигурност. Възможно е да сте се свързали с извършител на атака.</translation>
+<translation id="4394049700291259645">Деактивиране</translation>
+<translation id="4424024547088906515">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; Chrome няма доверие на сертификата му за сигурност. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="443673843213245140">Използването на прокси сървър е деактивирано, но е посочена изрична негова конфигурация.</translation>
-<translation id="4506176782989081258">Грешка при потвърждаването: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Грешка при потвърждаването: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Адресът да се премахне ли от Chrome?</translation>
<translation id="4594403342090139922">&amp;Отмяна на изтриването</translation>
<translation id="4607653538520819196">Икономия на данни не може да служи като прокси сървър за тази страница.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; сертификатът му за сигурност съдържа грешки. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="4726672564094551039">Презареждане на правилата</translation>
+<translation id="4728558894243024398">Платформа</translation>
+<translation id="4771973620359291008">Възникна неизвестна грешка.</translation>
<translation id="4800132727771399293">Прегледайте датата на валидност и кода за проверка и оптитайте отново</translation>
<translation id="4813512666221746211">Грешка в мрежата</translation>
+<translation id="4816492930507672669">Да се побере в страницата</translation>
<translation id="4850886885716139402">Изглед</translation>
-<translation id="4923417429809017348">Тази страница е преведена от непознат език на <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Тази страница е преведена от непознат език на <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Трябва да се посочи.</translation>
<translation id="4968547170521245791">Работата като прокси сървър не е възможна</translation>
-<translation id="498957508165411911">Да се преведе ли от <ph name="ORIGINAL_LANGUAGE"/> на <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Да се преведе ли от <ph name="ORIGINAL_LANGUAGE" /> на <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Допълнителното хранилище е в лошо състояние</translation>
<translation id="5031870354684148875">Всичко за Google Преводач</translation>
+<translation id="5045550434625856497">Неправилна парола</translation>
+<translation id="5087286274860437796">Понастоящем сертификатът на сървъра не е валиден.</translation>
<translation id="5089810972385038852">Щат</translation>
+<translation id="5094747076828555589">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; Chromium няма доверие на сертификата му за сигурност. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="5095208057601539847">Провинция</translation>
<translation id="5145883236150621069">В отговора за правилото присъства код на грешка</translation>
<translation id="5172758083709347301">Машината</translation>
-<translation id="5179510805599951267">Не е на <ph name="ORIGINAL_LANGUAGE"/>? Подайте сигнал за тази грешка</translation>
+<translation id="5179510805599951267">Не е на <ph name="ORIGINAL_LANGUAGE" />? Подайте сигнал за тази грешка</translation>
<translation id="5190835502935405962">Лента на отметките</translation>
+<translation id="5199729219167945352">Експерименти</translation>
+<translation id="5251803541071282808">Облак</translation>
<translation id="5295309862264981122">Потвърждение на навигацията</translation>
<translation id="5299298092464848405">Грешка при синтактичния анализ на правилото</translation>
+<translation id="5316812925700871227">Завъртане обратно на часовниковата стрелка</translation>
<translation id="5317780077021120954">Запазване</translation>
<translation id="536296301121032821">Съхраняването на настройките за правилото не бе успешно</translation>
-<translation id="5439770059721715174">При потвърждаване на схемата възникна грешка в/ъв „<ph name="ERROR_PATH"/>“: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Понастоящем сертификатът му за сигурност не е валиден. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от извършител на атака.</translation>
+<translation id="5439770059721715174">При потвърждаване на схемата възникна грешка в/ъв „<ph name="ERROR_PATH" />“: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Невалидно клеймо за дата и час на правилото</translation>
<translation id="5470861586879999274">&amp;Възстановяване на редактирането</translation>
<translation id="5509780412636533143">Управлявани отметки</translation>
<translation id="5523118979700054094">Име на правилото</translation>
<translation id="552553974213252141">Текстът правилно ли бе извлечен?</translation>
<translation id="5540224163453853">Заявената статия не можа да бъде намерена.</translation>
+<translation id="5556459405103347317">Повторно зареждане</translation>
<translation id="5565735124758917034">Активно</translation>
<translation id="560412284261940334">Управлението не се поддържа</translation>
<translation id="5629630648637658800">Зареждането на настройките за правилото не бе успешно</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Текущият потребител</translation>
<translation id="5813119285467412249">&amp;Възстановяване на добавянето</translation>
<translation id="5872918882028971132">Основни предложения</translation>
-<translation id="587701087903783706">Затваряне на изгледа за мобилни устройства</translation>
<translation id="59107663811261420">Този тип карта не се поддържа от Google Payments за този търговец. Моля, изберете друга.</translation>
+<translation id="5975083100439434680">Намаляване на мащаба</translation>
<translation id="5989320800837274978">Не са посочени нито фиксирани прокси сървъри, нито URL адрес на скрипт във формат .pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Затваряне</translation>
+<translation id="6060685159320643512">Внимавайте, тези експерименти може да са опасни</translation>
+<translation id="6151417162996330722">Сертификатът на сървъра има твърде дълъг период на валидност.</translation>
<translation id="6154808779448689242">Изведеното означение на правилото не съответства на текущото</translation>
<translation id="6165508094623778733">Научете повече</translation>
<translation id="6259156558325130047">&amp;Възстановяване на пренареждането</translation>
-<translation id="6263376278284652872">Отметки от <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Отметки от <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Пощенски код</translation>
<translation id="6337534724793800597">Филтриране на правилата по име</translation>
+<translation id="6387478394221739770">Търсите интересни нови функции на Chrome? Изпробвайте бета канала на адрес chrome.com/beta.</translation>
+<translation id="6426993025560594914">На платформата ви са налице всички експерименти!</translation>
<translation id="6445051938772793705">Държава</translation>
<translation id="6458467102616083041">Бе пренебрегнато, защото основното търсене е деактивирано от правило.</translation>
<translation id="647261751007945333">Правила за устройството</translation>
<translation id="6512448926095770873">Излизане от тази страница</translation>
<translation id="6529602333819889595">&amp;Възстановяване на изтриването</translation>
<translation id="6550675742724504774">Опции</translation>
-<translation id="6597614308054261376">Опитвате се да достигнете до <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Понастоящем Икономия на данни не може да служи като прокси сървър за тази страница.</translation>
-<translation id="6628463337424475685">Търсене с/ъс <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Опитвате се да достигнете до <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Понастоящем Икономия на данни не може да служи като прокси сървър за тази страница.</translation>
+<translation id="6628463337424475685">Търсене с/ъс <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Това правило е оттеглено.</translation>
<translation id="6646897916597483132">Въведете четирицифрения код за проверка от лицевата страна на картата си</translation>
+<translation id="674375294223700098">Неизвестна грешка в сертификата на сървъра.</translation>
<translation id="6753269504797312559">Стойност за правилото</translation>
<translation id="6831043979455480757">Превод</translation>
<translation id="6839929833149231406">Район</translation>
<translation id="6874604403660855544">&amp;Възстановяване на добавянето</translation>
<translation id="6891596781022320156">Нивото на правилото не се поддържа.</translation>
<translation id="6915804003454593391">Потребител:</translation>
+<translation id="6957887021205513506">Изглежда, че сертификатът на сървъра е подправен.</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6965978654500191972">Устройство</translation>
<translation id="6970216967273061347">Окръг</translation>
<translation id="6973656660372572881">Посочени са както фиксирани прокси сървъри, така и URL адрес на скрипт във формат .pac.</translation>
<translation id="6980028882292583085">Уведомление за JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Опитахте да се свържете с/ъс <ph name="DOMAIN" />, но сървърът предостави сертификат, чийто период на валидност е твърде дълъг, за да е надежден.</translation>
<translation id="7087282848513945231">Окръг</translation>
-<translation id="7108649287766967076">Преводът на <ph name="TARGET_LANGUAGE"/> не бе успешен.</translation>
+<translation id="7108649287766967076">Преводът на <ph name="TARGET_LANGUAGE" /> не бе успешен.</translation>
<translation id="7139724024395191329">Емирство</translation>
+<translation id="7179921470347911571">Стартиране отново сега</translation>
<translation id="7180611975245234373">Опресняване</translation>
<translation id="7182878459783632708">Няма зададени правила</translation>
-<translation id="7186367841673660872">Тази страница е преведена от<ph name="ORIGINAL_LANGUAGE"/>на<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="7186367841673660872">Тази страница е преведена от<ph name="ORIGINAL_LANGUAGE" />на<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Търсене с <ph name="SITE_NAME"/> на <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Търсене с <ph name="SITE_NAME" /> на <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Не може да се установи частна връзка с/ъс <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, тъй като датата и часът на компютъра ви (<ph name="DATE_AND_TIME" />) са неправилни.</translation>
<translation id="7275334191706090484">Управлявани отметки</translation>
<translation id="7298195798382681320">Препоръчително</translation>
<translation id="7334320624316649418">&amp;Възстановяване на пренареждането</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">Javascript</translation>
<translation id="7537536606612762813">Задължително</translation>
<translation id="7542995811387359312">Автоматичното попълване на кредитната карта е деактивирано, защото този формуляр не използва защитена връзка.</translation>
-<translation id="7568593326407688803">Тази страница е на<ph name="ORIGINAL_LANGUAGE"/>Искате ли да я преведете?</translation>
+<translation id="7567204685887185387">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; възможно е сертификатът му за сигурност да е издаден измамнически. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
+<translation id="7568593326407688803">Тази страница е на<ph name="ORIGINAL_LANGUAGE" />Искате ли да я преведете?</translation>
<translation id="7569952961197462199">Кредитната карта да се премахне ли от Chrome?</translation>
-<translation id="7600965453749440009">Никога да не се превежда от <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Стойността е извън обхват <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Сертификатът на сървъра нарушава ограниченията за име.</translation>
+<translation id="7600965453749440009">Никога да не се превежда от <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Стойността е извън обхват <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Търсите интересни нови функции на Chrome? Изпробвайте канала за програмисти на адрес chrome.com/dev.</translation>
<translation id="7752995774971033316">Не се управлява</translation>
+<translation id="7761701407923456692">Сертификатът на сървъра не съответства на URL адреса.</translation>
<translation id="777702478322588152">Префектура</translation>
<translation id="7791543448312431591">Добавяне</translation>
<translation id="7805768142964895445">Състояние</translation>
<translation id="7813600968533626083">Предложението за формуляри да се премахне ли от Chrome?</translation>
<translation id="7887683347370398519">Прегледайте кода за проверка и опитайте отново</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Сертификатът на сървъра още не е валиден.</translation>
<translation id="7956713633345437162">Мобилни отметки</translation>
<translation id="7961015016161918242">Никога</translation>
<translation id="7977590112176369853">&lt;въведете заявка&gt;</translation>
-<translation id="7983301409776629893">Винаги да се превежда от <ph name="ORIGINAL_LANGUAGE"/> на <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Винаги да се превежда от <ph name="ORIGINAL_LANGUAGE" /> на <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Настолни отметки</translation>
<translation id="7995512525968007366">Не е посочено</translation>
-<translation id="8034522405403831421">Тази страница е на <ph name="SOURCE_LANGUAGE"/>. Да се преведе ли на <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Принудително зададено в корпоративна среда</translation>
+<translation id="8034522405403831421">Тази страница е на <ph name="SOURCE_LANGUAGE" />. Да се преведе ли на <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Преглеждането на статията не бе успешно.</translation>
<translation id="8091372947890762290">В сървъра се изчаква активиране</translation>
<translation id="8194797478851900357">&amp;Отмяна на преместването</translation>
-<translation id="8201077131113104583">Невалиден URL адрес за актуализиране на разширението с идентификационен номер <ph name="EXTENSION_ID"/>.</translation>
+<translation id="8201077131113104583">Невалиден URL адрес за актуализиране на разширението с идентификационен номер <ph name="EXTENSION_ID" />.</translation>
<translation id="8208216423136871611">Без запазване</translation>
<translation id="8218327578424803826">Зададено местоположение:</translation>
<translation id="8249320324621329438">Последно извличане:</translation>
+<translation id="8294431847097064396">Източник</translation>
<translation id="8308427013383895095">Преводът не бе успешен поради проблем с връзката към мрежата.</translation>
<translation id="8311778656528046050">Наистина ли искате да презаредите тази страница?</translation>
<translation id="8349305172487531364">Лента на отметките</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Прилага се към</translation>
<translation id="8530504477309582336">Този тип карта не се поддържа от Google Payments. Моля, изберете друга.</translation>
<translation id="8553075262323480129">Преводът не бе успешен, защото езикът на страницата не можа да бъде определен.</translation>
-<translation id="8571890674111243710">Превод на страницата на <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Не може да се установи частна връзка с/ъс <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, тъй като датата и часът на устройството ви (<ph name="DATE_AND_TIME" />) са неправилни.</translation>
+<translation id="8571890674111243710">Превод на страницата на <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Възстановяване на всичко към стандартното състояние</translation>
<translation id="8713130696108419660">Лош подпис посредством първоначалния ключ</translation>
<translation id="8725066075913043281">Опитайте отново</translation>
+<translation id="8738058698779197622">За установяване на сигурна връзка е необходимо часовникът ви да е верен. Това е така, защото сертификатите, с които уебсайтовете се идентифицират, са валидни само за конкретни периоди от време. Тъй като часовникът на устройството ви не е верен, Chromium не може да потвърди тези сертификати.</translation>
<translation id="8790007591277257123">&amp;Възстановяване на изтриването</translation>
<translation id="8804164990146287819">Декларация за поверителност</translation>
+<translation id="8820817407110198400">Отметки</translation>
<translation id="8824019021993735287">Chrome не можа да потвърди картата ви. Моля, опитайте отново по-късно.</translation>
<translation id="8834246243508017242">Активиране на използването на контактите при автоматично попълване…</translation>
<translation id="883848425547221593">Други отметки</translation>
+<translation id="884923133447025588">Не е намерен механизъм за анулиране.</translation>
<translation id="8866481888320382733">Грешка при синтактичния анализ на настройките за правилото</translation>
<translation id="8876793034577346603">Синтактичният анализ на конфигурацията на мрежата не бе успешен.</translation>
<translation id="8891727572606052622">Невалиден режим на прокси сървъра.</translation>
-<translation id="8940229512486821554">Изпълнете командата за <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">За съжаление този експеримент не се предлага за платформата ви.</translation>
+<translation id="8903921497873541725">Увеличаване на мащаба</translation>
+<translation id="8932102934695377596">Часовникът ви е назад</translation>
+<translation id="8940229512486821554">Изпълнете командата за <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Сертификатът на сървъра е с изтекла валидност.</translation>
<translation id="8988760548304185580">Въведете датата на валидност и трицифрения код за проверка от гърба на картата си</translation>
-<translation id="9020542370529661692">Тази страница е преведена на <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Флаговете, които се прилагат за цялата система, могат да бъдат зададени само от собственика: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Тази страница е преведена на <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Опитахте да отворите <ph name="DOMAIN" />, но сървърът предостави невалиден сертификат.</translation>
<translation id="9125941078353557812">Въведете трицифрения код за проверка от гърба на картата си</translation>
<translation id="9137013805542155359">Показване на оригинала</translation>
<translation id="9148507642005240123">&amp;Отмяна на редактирането</translation>
<translation id="9154176715500758432">Нека остана на тази страница</translation>
<translation id="9170848237812810038">&amp;Отмяна</translation>
+<translation id="917450738466192189">Сертификатът на сървъра е невалиден.</translation>
+<translation id="9187827965378254003">Ужас! Изглежда, че понастоящем няма налични експерименти.</translation>
<translation id="9207861905230894330">Добавянето на статията не бе успешно.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ИЗЧИСТВАНЕ НА ФОРМУЛЯРА</translation>
+<translation id="988159990683914416">Компилирана програма за програмисти</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_bn.xtb b/chromium/components/strings/components_strings_bn.xtb
index c7e857a2954..321ecbc7180 100644
--- a/chromium/components/strings/components_strings_bn.xtb
+++ b/chromium/components/strings/components_strings_bn.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="bn">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="bn">
+<translation id="1032854598605920125">ঘড়ির কাঁটার দিকে ঘোরান</translation>
<translation id="1055184225775184556">&amp;যোগ করাকে পূর্বাবস্থায় ফেরান</translation>
<translation id="106701514854093668">ডেস্কটপ বুকমার্ক</translation>
-<translation id="1103523840287552314">সর্বদা অনুবাদ করুন <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">প্রস্থের মধ্যে আঁটান</translation>
+<translation id="1103523840287552314">সর্বদা অনুবাদ করুন <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;পুনর্বিন্যাসকে পূর্বাবস্থায় ফেরান</translation>
<translation id="111844081046043029">আপনি এই পৃষ্ঠাটি ছেড়ে যাওয়ার ব্যাপারে কি নিশ্চিত?</translation>
<translation id="112840717907525620">নীতি ক্যাশেটি ঠিক আছে</translation>
<translation id="1132774398110320017">Chrome স্বতঃপূর্ণ সেটিংস...</translation>
-<translation id="1152921474424827756"><ph name="URL"/> এর <ph name="BEGIN_LINK"/>ক্যাশে করা অনুলিপি<ph name="END_LINK"/> অ্যাক্সেস করুন</translation>
+<translation id="1150979032973867961">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্রটি আপনার কম্পিউটারের নিকট বিশ্বাসযোগ্য নয়। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
+<translation id="1152921474424827756"><ph name="URL" /> এর <ph name="BEGIN_LINK" />ক্যাশে করা অনুলিপি<ph name="END_LINK" /> অ্যাক্সেস করুন</translation>
+<translation id="121201262018556460">আপনি <ph name="DOMAIN" />-এ পৌঁছানোর প্রচেষ্টা করেছেন, কিন্তু সার্ভার একটি দুর্বল কী সম্বলিত শংসাপত্র উপস্থাপন করেছে৷ কোনো আক্রমণকারী ব্যক্তিগত কী ভঙ্গ করে থাকতে পারে এবং সার্ভারটি আপনার প্রত্যাশিত সার্ভার নাও হতে পারে (হতে পারে আপনি একজন আক্রমণকারীর সাথে যোগাযোগ করছেন)৷</translation>
<translation id="1227224963052638717">অজানা নীতি৷</translation>
<translation id="1227633850867390598">মান লুকান</translation>
<translation id="1228893227497259893">ভুল সত্তা সনাক্তকারী</translation>
@@ -14,66 +20,78 @@
<translation id="1339601241726513588">ডোমেন নথিভুক্ত করুন:</translation>
<translation id="1344588688991793829">Chromium স্বতঃপূর্ণ সেটিংস...</translation>
<translation id="1426410128494586442">হ্যাঁ</translation>
+<translation id="1430915738399379752">মুদ্রণ</translation>
<translation id="1455235771979731432">আপনার কার্ডটি যাচাই করতে একটি সমস্যা হয়েছিল৷ আপনার ইন্টারনেট সংযোগ পরীক্ষা করুন এবং আবার চেষ্টা করুন৷</translation>
<translation id="1491151370853475546">এই পৃষ্ঠাটি পুনঃ লোড করুন</translation>
<translation id="1549470594296187301">এই বৈশিষ্ট্যটি ব্যবহার করার জন্য JavaScript সক্ষম করা প্রয়োজন।</translation>
-<translation id="1639239467298939599">লোড হচ্ছে</translation>
<translation id="1640180200866533862">ব্যবহারকারীর নীতিসমূহ</translation>
<translation id="1644184664548287040">নেটওয়ার্ক কনফিগারেশনটি অবৈধ এবং আমদানি করা যায়নি৷</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> এর পৃষ্ঠাটি জানাচ্ছে:</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="168841957122794586">সার্ভার শংসাপত্রে একটি দুর্বল কপিরাইট কী আছে৷</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> এর পৃষ্ঠাটি জানাচ্ছে:</translation>
+<translation id="1706954506755087368">{1,plural, =1{এই সার্ভার যে <ph name="DOMAIN" /> তা এটি প্রমাণ করতে পারেনি; এর নিরাপত্তা শংসাপত্রটি আগামীকালের বলে মনে হচ্ছে। কোনো ভুল কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপ্রদানকারী কোনো আক্রমণকারীর কারণে এমনটি হতে পারে।}one{এই সার্ভার যে <ph name="DOMAIN" /> তা এটি প্রমাণ করতে পারেনি; এর নিরাপত্তা শংসাপত্রটি আগামী # দিন পরের বলে মনে হচ্ছে। কোনো ভুল কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপ্রদানকারী কোনো আক্রমণকারীর কারণে এমনটি হতে পারে।}other{এই সার্ভার যে <ph name="DOMAIN" /> তা এটি প্রমাণ করতে পারেনি; এর নিরাপত্তা শংসাপত্রটি আগামী # দিন পরের বলে মনে হচ্ছে। কোনো ভুল কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপ্রদানকারী কোনো আক্রমণকারীর কারণে এমনটি হতে পারে।}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্রটি আপনার ডিভােইসের নিকট বিশ্বাসযোগ্য নয়। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
<translation id="1821930232296380041">অবৈধ অনুরোধ বা অনুরোধ মাপকাঠিগুলি</translation>
-<translation id="1853748787962613237">নিবন্ধ প্রদর্শন করতে ব্যর্থ হয়েছে৷</translation>
<translation id="1871208020102129563">
প্রক্সি স্থির প্রক্সি সার্ভারগুলি ব্যবহার করতে সেট করা আছে কোনো .pac স্ক্রিপ্ট URL নয়৷</translation>
-<translation id="1875753206475436906">অনুসন্ধানমূলক প্রকার: <ph name="HEURISTIC_TYPE"/>
- সার্ভারের প্রকার: <ph name="SERVER_TYPE"/>
- ক্ষেত্র স্বাক্ষর: <ph name="FIELD_SIGNATURE"/>
- ফর্ম স্বাক্ষর: <ph name="FORM_SIGNATURE"/>
- গবেষণা আইডি: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158"><ph name="LINK"/> এ যান</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> বুকমার্কগুলি</translation>
+<translation id="194030505837763158"><ph name="LINK" /> এ যান</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> বুকমার্কগুলি</translation>
<translation id="1973335181906896915">ধারাবাহিকতাতে ত্রুটি</translation>
+<translation id="1974060860693918893">উন্নত</translation>
<translation id="2025186561304664664">স্বতঃ কনফিগার করতে প্রক্সি সেট করা হয়৷</translation>
<translation id="2025623846716345241">পুনঃলোড নিশ্চিত করুন</translation>
-<translation id="2030481566774242610">আপনি কি <ph name="LINK"/> বোঝাতে চেয়েছিলেন?</translation>
+<translation id="2030481566774242610">আপনি কি <ph name="LINK" /> বোঝাতে চেয়েছিলেন?</translation>
<translation id="2053553514270667976">পিন কোড</translation>
<translation id="20817612488360358">সিস্টেম প্রক্সি সেটিংস ব্যবহার করার জন্য সেট আছে কিন্তু একটি সুনির্দিষ্ট প্রক্সি কনফিগারেশনও নির্দিষ্ট করা আছে৷</translation>
<translation id="2094505752054353250">ডোমেন মেলেনি</translation>
<translation id="2096368010154057602">বিভাগ</translation>
<translation id="2113977810652731515">কার্ড</translation>
-<translation id="2114841414352855701">এড়িয়ে যাওয়া হয়েছে কারণ এটি <ph name="POLICY_NAME"/>-দ্বারা ওভাররাইড করা হয়েছিল৷</translation>
+<translation id="2114841414352855701">এড়িয়ে যাওয়া হয়েছে কারণ এটি <ph name="POLICY_NAME" />-দ্বারা ওভাররাইড করা হয়েছিল৷</translation>
+<translation id="2128531968068887769">নেটিভ ক্লায়েন্ট</translation>
<translation id="213826338245044447">মোবাইল বুকমার্ক</translation>
+<translation id="2171101176734966184">আপনি <ph name="DOMAIN" />-এ পৌঁছানোর প্রচেষ্টা করেছেন, কিন্তু সার্ভারটি একটি দুর্বল অ্যালগারিদম স্বাক্ষর ব্যবহার করে একটি স্বাক্ষরিত শংসাপত্র উপস্থাপন করেছে৷ এর অর্থ হ'ল সার্ভার যে সুরক্ষা প্রমাণপত্রাদি উপস্থাপন করেছে তা জাল হতে পারে এবং সার্ভারটি আপনার প্রত্যাশিত সার্ভার নাও হতে পারে (হতে পারে আপনি একজন আক্রমণকারীর সাথে যোগাযোগ করছেন)৷</translation>
<translation id="2181821976797666341">নীতিসমূহ</translation>
<translation id="2212735316055980242">নীতি পাওয়া যায়নি</translation>
<translation id="2213606439339815911">এন্ট্রিগুলি আনা হচ্ছে...</translation>
<translation id="225207911366869382">এই মান এই নীতির জন্য অসমর্থিত হয়েছে৷</translation>
<translation id="2262243747453050782">HTTP ত্রুটি</translation>
-<translation id="2270192940992995399">নিবন্ধ খুঁজতে ব্যর্থ হয়েছে৷</translation>
-<translation id="2328300916057834155"><ph name="ENTRY_INDEX"/> সূচিতে অবৈধ বুকমার্ক এড়িয়ে যাওয়া হয়েছে</translation>
+<translation id="2282872951544483773">অনুপলব্ধ পরীক্ষানিরীক্ষাগুলি</translation>
+<translation id="229702904922032456">একটি রুট বা মধ্যবর্তী শংসাপত্রের মেয়াদ শেষ হয়েছে৷</translation>
+<translation id="2328300916057834155"><ph name="ENTRY_INDEX" /> সূচিতে অবৈধ বুকমার্ক এড়িয়ে যাওয়া হয়েছে</translation>
<translation id="2354001756790975382">অন্য বুকমার্কস</translation>
<translation id="2359808026110333948">অবিরত</translation>
<translation id="2367567093518048410">স্তর</translation>
+<translation id="2384307209577226199">এন্টারপ্রাইজ ডিফল্ট</translation>
+<translation id="2386255080630008482">সার্ভারের শংসাপত্রটি প্রত্যাহার করা হয়েছে৷</translation>
<translation id="2392959068659972793">কোনো মান সেট করা নেই এমন নীতিগুলি দেখান</translation>
<translation id="2396249848217231973">&amp;মুছে ফেলাকে পূর্বাবস্থায় ফেরান</translation>
+<translation id="2413528052993050574">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্র প্রত্যাহার করা হতে পারে। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
<translation id="2455981314101692989">এই ওয়েবপৃষ্ঠাটি এই ফর্মটির জন্য স্বয়ংক্রিয় পূরণ ফর্মকে অক্ষম করেছে৷</translation>
<translation id="2479410451996844060">অবৈধ অনুসন্ধানের URL৷</translation>
+<translation id="2491120439723279231">সার্ভারের শংসাপত্রে ত্রুটি আছে৷</translation>
<translation id="2495083838625180221">JSON বিশ্লেষক</translation>
<translation id="2498091847651709837">নতুন কার্ড স্ক্যান করুন</translation>
<translation id="2556876185419854533">&amp;সম্পাদনাকে পূর্বাবস্থায় ফেরান</translation>
-<translation id="2581221116934462656">আপনি কি পরবর্তী সময়ে এই সাইটটির <ph name="LANGUAGE_NAME"/> পৃষ্ঠাগুলিকে অনুবাদ করে দেওয়ার জন্য <ph name="PRODUCT_NAME"/> কে বলতে চান?</translation>
+<translation id="2581221116934462656">আপনি কি পরবর্তী সময়ে এই সাইটটির <ph name="LANGUAGE_NAME" /> পৃষ্ঠাগুলিকে অনুবাদ করে দেওয়ার জন্য <ph name="PRODUCT_NAME" /> কে বলতে চান?</translation>
<translation id="2587841377698384444">ডিরেক্টরি API আইডি:</translation>
<translation id="2597378329261239068">এই দস্তাবেজটি পাসওয়ার্ড সুরক্ষিত৷ দয়া করে একটি পাসওয়ার্ড লিখুন৷</translation>
+<translation id="2625385379895617796">আপনার ঘড়ির সময় অনেকটা এগিয়ে</translation>
<translation id="2639739919103226564">স্থিতি: </translation>
+<translation id="2653659639078652383">জমা</translation>
<translation id="2704283930420550640">বিন্যাসের সাথে মূল্য মেলে না৷</translation>
<translation id="2721148159707890343">অনুরোধ সফল হয়েছে</translation>
+<translation id="2728127805433021124">একটি দুর্বল স্বাক্ষর অ্যালগোরিদম ব্যবহার করে সার্ভারের শংসাপত্রে সাইন করা হয়েছে৷</translation>
<translation id="2774256287122201187">আপনি অবিরত রাখতে পারেন৷ আপনি যদি পৃষ্ঠাটিতে অবিরত করেন এই সতর্কতা পরবর্তী পাঁচ মিনিটের জন্য উপস্থিত হবে না৷</translation>
<translation id="277499241957683684">ডিভাইস রেকর্ড অনুপস্থিত</translation>
<translation id="2835170189407361413">ফর্ম সাফ করুন</translation>
-<translation id="2855922900409897335">আপনার <ph name="CREDIT_CARD"/> যাচাই করুন৷</translation>
+<translation id="2855922900409897335">আপনার <ph name="CREDIT_CARD" /> যাচাই করুন৷</translation>
+<translation id="2915500479781995473">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্রটির মেয়াদোত্তীর্ণ হয়ে গেছে৷ কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে৷ আপনার কম্পিউটারের ঘড়িটি বর্তমানে <ph name="CURRENT_TIME" /> হিসেবে সেট করা আছে৷ এটি কি ঠিক আছে? ঠিক না থাকলে, আপনার সিস্টেম ঘড়িটি ঠিক করে পৃষ্ঠাটি রিফ্রেশ করা উচিৎ৷</translation>
+<translation id="2922350208395188000">সার্ভারের শংসাপত্র চেক করা যাবে না৷</translation>
+<translation id="2941952326391522266">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্র <ph name="DOMAIN2" /> থেকে পাওয়া। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
<translation id="2958431318199492670">নেটওয়ার্ক কনফিগারেশন ONC মানকের সাথে সম্মত নয়৷ কনফিগারেশনের অংশগুলি আমদানিকৃত নাও হতে পারে৷</translation>
<translation id="2972581237482394796">&amp;পুনরায় করুন</translation>
-<translation id="3010559122411665027">তালিকার এন্ট্রি &quot; <ph name="ENTRY_INDEX"/> &quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">তালিকার এন্ট্রি " <ph name="ENTRY_INDEX" /> ": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">নীতির ভুল প্রকার</translation>
<translation id="3105172416063519923">সম্পদ আইডি:</translation>
<translation id="3145945101586104090">প্রতিক্রিয়া ডিকোড করতে ব্যর্থ হয়েছে</translation>
@@ -81,32 +99,42 @@
<translation id="3169472444629675720">আবিষ্কার করুন</translation>
<translation id="3174168572213147020">দ্বীপ</translation>
<translation id="3219579145727097045">আপনার কার্ডের সামনে থাকা ৪ সংখ্যার CVC এবং মেয়াদ শেষের তারিখ লিখুন</translation>
-<translation id="3228969707346345236">পৃষ্ঠাটি ইতিমধ্যে <ph name="LANGUAGE"/>-এ থাকার কারণে অনুবাদ ব্যর্থ হয়েছে৷</translation>
+<translation id="3225919329040284222">সার্ভারটি এমন একটি শংসাপত্র উপস্থাপনা করেছে যা বিল্ট-ইন প্রত্যাশাগুলির সাথে মেলে না৷ এই প্রত্যাশাগুলি আপনাকে সুরক্ষিত করতে কিছু নিশ্চিত, উচ্চ সুরক্ষার ওয়েবসাইটের জন্য অন্তর্ভুক্ত৷</translation>
+<translation id="3228969707346345236">পৃষ্ঠাটি ইতিমধ্যে <ph name="LANGUAGE" />-এ থাকার কারণে অনুবাদ ব্যর্থ হয়েছে৷</translation>
<translation id="3270847123878663523">&amp;পুনর্বিন্যাসকে পূর্বাবস্থায় ফেরান</translation>
+<translation id="3286538390144397061">এখন পুর্নসূচনা করবেন</translation>
<translation id="333371639341676808">এই পৃষ্ঠাটিকে অতিরিক্ত কথোপকথন তৈরি করা থেকে আটকান৷</translation>
-<translation id="3369366829301677151">আপনার <ph name="CREDIT_CARD"/> আপডেট করুন এবং যাচাই করুন</translation>
+<translation id="3340978935015468852">সেটিংস</translation>
+<translation id="3369192424181595722">ঘড়ির ত্রুটি</translation>
+<translation id="3369366829301677151">আপনার <ph name="CREDIT_CARD" /> আপডেট করুন এবং যাচাই করুন</translation>
<translation id="337363190475750230">প্রদান করবে না</translation>
<translation id="3377188786107721145">নীতি বিশ্লেষণ ত্রুটি</translation>
<translation id="3380365263193509176">অজানা ত্রুটি</translation>
<translation id="3380864720620200369">ক্লায়েন্ট ID:</translation>
<translation id="3427342743765426898">&amp;সম্পাদনাকে পুনরায় করুন</translation>
+<translation id="3435896845095436175">সক্ষম করুন</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">বিরামকাল প্রাপ্ত করুন:</translation>
+<translation id="3462200631372590220">উন্নত করার বিশদ বিবরণ, লুকান</translation>
+<translation id="3528171143076753409">সার্ভারের শংসাপত্র বিশ্বস্ত নয়৷</translation>
<translation id="3542684924769048008">এর জন্য পাসওয়ার্ড ব্যবহার করুন:</translation>
<translation id="3583757800736429874">&amp;সরানোর কাজটি পুনরায় করুন</translation>
<translation id="3623476034248543066">মান দেখান</translation>
+<translation id="3648607100222897006">এই পরীক্ষামূলক বৈশিষ্ট্যগুলি যেকোনো সময়ে পরিবর্তন, ভঙ্গ বা অদৃশ্য হয়ে যেতে পারে৷ আপনি এই পরীক্ষাগুলির যেকোনো একটি চালু করতে কী ঘটতে পারে সে সম্পর্কে আমরা কোনো রকম নিশ্চয়তা দিই না এবং এমনকি আপনার ব্রাউজার তাত্ক্ষণিকভাবে বিস্ফোরণ ঘটাতে পারে৷ মজা সরিয়ে, আপনার ব্রাউজার আপনার সকল ডেটা মুছে দিতে পারে, বা আপনার সুরক্ষা ও গোপনীয়তা অপ্রত্যাশিতভাবে ক্ষতিগ্রস্থ হতে পারে৷ আপনার দ্বারা সক্রিয় করা যেকোনো পরীক্ষা এই ব্রাউজারের সমস্ত ব্যবহারকারীদের জন্য সক্রিয় হবে৷ দয়া করে সাবধানতার সাথে এগিয়ে যান৷</translation>
<translation id="3650584904733503804">বৈধতা যাচাইকরণ সফল হয়েছে</translation>
<translation id="370665806235115550">লোড হচ্ছে...</translation>
<translation id="3712624925041724820">লাইসেন্সগুলির মেয়াদ শেষ হয়ে গেছে</translation>
<translation id="3739623965217189342">আপনার অনুলিপি করা লিঙ্ক</translation>
<translation id="375403751935624634">একটি সার্ভার ত্রুটির কারণে অনুবাদ ব্যর্থ হয়েছে৷</translation>
<translation id="385051799172605136">ফিরুন</translation>
+<translation id="3858027520442213535">তারিখ এবং সময় আপডেট করুন</translation>
<translation id="3884278016824448484">পরস্পর বিরোধী ডিভাইস সনাক্তকারী</translation>
<translation id="3885155851504623709">পারিশ</translation>
<translation id="3934680773876859118">PDF দস্তাবেজ লোড হতে ব্যর্থ</translation>
<translation id="3963721102035795474">পাঠক মোড</translation>
<translation id="4030383055268325496">&amp;যোগ করাকে পূর্বাবস্থায় ফেরান</translation>
-<translation id="4058922952496707368">কী &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">সতর্কতা</translation>
+<translation id="4058922952496707368">কী "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">প্রক্সি কনফিগারেশনটি .pac স্ক্রিপ্ট URL-এ ব্যবহার করাতে সেট থাকে স্থির প্রক্সি সার্ভারগুলিতে নয়৷</translation>
<translation id="409504436206021213">পুনঃলোড করবেন না</translation>
<translation id="4103249731201008433">ডিভাইসের ক্রমিক সংখ্যা অবৈধ</translation>
@@ -119,40 +147,56 @@
<translation id="4258748452823770588">ত্রুটিপূর্ণ স্বাক্ষর</translation>
<translation id="4269787794583293679">(কোনো ব্যবহারকারীর নাম নেই)</translation>
<translation id="4300246636397505754">মূল প্রস্তাবনাগুলি</translation>
-<translation id="4372948949327679948">প্রত্যাশিত <ph name="VALUE_TYPE"/> মান৷</translation>
+<translation id="4325863107915753736">নিবন্ধ খুঁজে পেতে ব্যর্থ হয়েছে</translation>
+<translation id="4372948949327679948">প্রত্যাশিত <ph name="VALUE_TYPE" /> মান৷</translation>
+<translation id="4377125064752653719">আপনি <ph name="DOMAIN" />-এ পৌঁছানোর প্রচেষ্টা করেছেন, তবে সার্ভারটি যে শংসাপত্রটি উপস্থাপন করেছে সেটির জারিকর্তা সেটিকে প্রত্যাহার করেছে৷ এর অর্থ হ'ল সার্ভারটি যে সুরক্ষা প্রমানপত্র উপস্থাপন করেছে তা কোনওমতেই বিশ্বাসযোগ্য নয়৷ হতে পারে আপনি একজন আক্রমণকারীর সাথে যোগাযোগ করছেন৷</translation>
+<translation id="4394049700291259645">অক্ষম</translation>
+<translation id="4424024547088906515">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্র Chrome এর নিকট বিশ্বাসযোগ্য নয়। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
<translation id="443673843213245140">প্রক্সির ব্যবহার অক্ষম করা হয়েছে কিন্তু কোনো স্পষ্ট প্রক্সি কনফিগারেশান নির্দিষ্ট করা হয়েছে৷</translation>
-<translation id="4506176782989081258">যাচাইকরণের ত্রুটি: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">যাচাইকরণের ত্রুটি: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chrome থেকে ঠিকানা সরাবেন?</translation>
<translation id="4594403342090139922">&amp;মুছে ফেলাকে পূর্বাবস্থায় ফেরান</translation>
<translation id="4607653538520819196">এই পৃষ্ঠাটিকে ডেটা সেভার মারফত প্রক্সী করা যাবে না।</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্রে কিছু ত্রুটি আছে। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
<translation id="4726672564094551039">নীতিগুলি পুনঃলোড করুন</translation>
+<translation id="4728558894243024398">প্ল্যাটফর্ম</translation>
+<translation id="4771973620359291008">একটি অজানা ত্রুটি ঘটেছে৷</translation>
<translation id="4800132727771399293">আপনার মেয়াদ শেষের তারিখ এবং CVC পরীক্ষা করুন এবং আবার চেষ্টা করুন</translation>
<translation id="4813512666221746211">নেটওয়ার্ক ত্রুটি</translation>
+<translation id="4816492930507672669">পৃষ্ঠাতে মানানসই</translation>
<translation id="4850886885716139402">দেখুন</translation>
-<translation id="4923417429809017348">এই পৃষ্ঠাটি কোন অজানা ভাষা থেকে <ph name="LANGUAGE_LANGUAGE"/>-এ অনুবাদ করা হয়েছে</translation>
+<translation id="4923417429809017348">এই পৃষ্ঠাটি কোন অজানা ভাষা থেকে <ph name="LANGUAGE_LANGUAGE" />-এ অনুবাদ করা হয়েছে</translation>
<translation id="4926049483395192435">নির্দিষ্ট করা উচিত৷</translation>
<translation id="4968547170521245791">প্রক্সী করা যাবে না</translation>
-<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE"/> থেকে <ph name="TARGET_LANGUAGE"/> তে অনুবাদ করবেন?</translation>
+<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE" /> থেকে <ph name="TARGET_LANGUAGE" /> তে অনুবাদ করবেন?</translation>
<translation id="5019198164206649151">ব্যাকিং স্টোরটি ত্রুটিপূর্ণ অবস্থায় আছে</translation>
<translation id="5031870354684148875">Google অনুবাদ সম্বন্ধে</translation>
+<translation id="5045550434625856497">ভুল পাসওয়ার্ড</translation>
+<translation id="5087286274860437796">সার্ভারের শংসাপত্র এই সময়ে বৈধ নয়৷</translation>
<translation id="5089810972385038852">রাজ্য</translation>
+<translation id="5094747076828555589">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্রটি Chromium এর নিকট বিশ্বাসযোগ্য নয়। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
<translation id="5095208057601539847">প্রদেশ</translation>
<translation id="5145883236150621069">নীতি প্রতিক্রিয়ার মধ্যে ত্রুটি কোড উপস্থিত</translation>
<translation id="5172758083709347301">যন্ত্র</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/>-এ নেই? এই ত্রুটি রিপোর্ট করুন</translation>
+<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" />-এ নেই? এই ত্রুটি রিপোর্ট করুন</translation>
<translation id="5190835502935405962">বুকমার্ক দণ্ড</translation>
+<translation id="5199729219167945352">পরীক্ষাদি</translation>
+<translation id="5251803541071282808">ক্লাউড</translation>
<translation id="5295309862264981122">নেভিগেশন নিশ্চিত করুন</translation>
<translation id="5299298092464848405">নীতি বিশ্লেষণ করার সময় ত্রুটি</translation>
+<translation id="5316812925700871227">ঘড়ির কাঁটার বিপরীত দিকে ঘোরান</translation>
<translation id="5317780077021120954">সংরক্ষণ করুন</translation>
<translation id="536296301121032821">নীতি সেটিংস সংরক্ষণ করতে ব্যর্থ হয়েছে</translation>
-<translation id="5439770059721715174">&quot;<ph name="ERROR_PATH"/>&quot; এ স্কিমা বৈধতার ত্রুটি হয়েছে: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্র এই সময়ে বৈধ নয়। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
+<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" এ স্কিমা বৈধতার ত্রুটি হয়েছে: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">ত্রুটিপূর্ণ নীতি টাইমস্ট্যাম্প</translation>
<translation id="5470861586879999274">&amp;সম্পাদনাকে পুনরায় করুন</translation>
<translation id="5509780412636533143">পরিচালিত বুকমার্কগুলি</translation>
<translation id="5523118979700054094">নীতি নাম</translation>
<translation id="552553974213252141">পাঠ্য কি সঠিকভাবে প্রাপ্ত হয়েছে?</translation>
<translation id="5540224163453853">অনুরোধকৃত নিবন্ধ খুঁজে পাওয়া যায়নি৷</translation>
+<translation id="5556459405103347317">পুনরায় লোড করুন</translation>
<translation id="5565735124758917034">সক্রিয়</translation>
<translation id="560412284261940334">পরিচালনা সমর্থিত নয়</translation>
<translation id="5629630648637658800">নীতি সেটিংস লোড করতে ব্যর্থ হয়েছে</translation>
@@ -160,46 +204,56 @@
<translation id="5720705177508910913">বর্তমান ব্যবহারকারী</translation>
<translation id="5813119285467412249">&amp;যোগ করাকে পুনরায় করুন</translation>
<translation id="5872918882028971132">মূল প্রস্তাবনাগুলি</translation>
-<translation id="587701087903783706">মোবাইল সহায়ক দৃশ্য বন্ধ করুন</translation>
<translation id="59107663811261420">এই বণিকের জন্য এই ধরনের কার্ড Google Payments দ্বারা সমর্থিত নয়৷ দয়া করে একটি আলাদা কার্ড নির্বাচন করুন৷</translation>
+<translation id="5975083100439434680">জুম কমান</translation>
<translation id="5989320800837274978">কোনো নির্ধারিত প্রক্সি সার্ভার অথবা একটি.pac স্ক্রিপ্ট UR সুর্নিদিষ্টভাবে উল্লেখ করা হয়নি৷</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">বন্ধ</translation>
+<translation id="6060685159320643512">সাবধান হন, এই পরীক্ষাগুলি সমস্যা সৃষ্টি করতে পারে</translation>
+<translation id="6151417162996330722">সার্ভারের শংসাপত্রের বৈধতার সময়সীমা আছে যা খুবই দীর্ঘ।</translation>
<translation id="6154808779448689242">ফিরে পাওয়া নীতি টোকেন বর্তমান টোকেনের সঙ্গে মেলে না</translation>
<translation id="6165508094623778733">আরো জানুন</translation>
<translation id="6259156558325130047">&amp;পুনর্বিন্যাসকে পুনরায় করুন</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> বুকমার্কগুলি</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> বুকমার্কগুলি</translation>
<translation id="6282194474023008486">পোস্টাল কোড</translation>
<translation id="6337534724793800597">নাম অনুসারে ফিল্টারগুলি বাছাই করুন</translation>
+<translation id="6387478394221739770">Chrome এর নতুন দুর্দান্ত বৈশিষ্ট্যগুলিতে আগ্রহী? chrome.com/beta এ আমাদের বিটা চ্যানেল ব্যবহার করে দেখুন৷</translation>
+<translation id="6426993025560594914">সব পরীক্ষাগুলি আপনার প্ল্যাটফর্মে রয়েছে!</translation>
<translation id="6445051938772793705">দেশ</translation>
<translation id="6458467102616083041">নীতি দ্বারা ডিফল্ট অনুসন্ধান অক্ষম করা হয়েছে সেই কারণে উপেক্ষা করা হয়েছে৷</translation>
<translation id="647261751007945333">ডিভাইস নীতিগুলি</translation>
<translation id="6512448926095770873">এই পৃষ্ঠাটি ত্যাগ করুন</translation>
<translation id="6529602333819889595">&amp;মুছে ফেলাকে পুনরায় করুন</translation>
<translation id="6550675742724504774">বিকল্পসমূহ</translation>
-<translation id="6597614308054261376">আপনি <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>-এ পৌঁছানোর চেষ্টা করছেন। এখন এই পৃষ্ঠাটি ডেটা সেভার মারফত প্রক্সী করা যাবে না।</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> অনুসন্ধান</translation>
+<translation id="6597614308054261376">আপনি <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />-এ পৌঁছানোর চেষ্টা করছেন। এখন এই পৃষ্ঠাটি ডেটা সেভার মারফত প্রক্সী করা যাবে না।</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> অনুসন্ধান</translation>
<translation id="6644283850729428850">এই নীতিটি অসমর্থিত হয়েছে৷</translation>
<translation id="6646897916597483132">আপনার কার্ডের সামনে থেকে ৪ সংখ্যার CVC লিখুন</translation>
+<translation id="674375294223700098">অজানা সার্ভার শংসাপত্র ত্রুটি৷</translation>
<translation id="6753269504797312559">নীতি মান</translation>
<translation id="6831043979455480757">অনুবাদ</translation>
<translation id="6839929833149231406">এলাকা</translation>
<translation id="6874604403660855544">&amp;যোগ করাকে পুনরায় করুন</translation>
<translation id="6891596781022320156">নীতি স্তর সমর্থিত নয়।</translation>
<translation id="6915804003454593391">ব্যবহারকারী:</translation>
+<translation id="6957887021205513506">সার্ভারটির শংসাপত্রটি একটি জাল হিসাবে উপস্থিত হয়েছে৷</translation>
<translation id="6965382102122355670">ওকে</translation>
<translation id="6965978654500191972">ডিভাইস</translation>
<translation id="6970216967273061347">জেলা</translation>
<translation id="6973656660372572881">স্থির প্রক্সি সার্ভার এবং .pac স্ক্রিপ্ট URL-এর উভয়ই নির্দিষ্ট আছে৷</translation>
<translation id="6980028882292583085">Javascript সতর্কতা</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">আমি <ph name="DOMAIN" />-এ সংযোগ করার চেষ্টা করেছেন, কিন্তু সার্ভার একটি শংসাপত্র উপস্থাপন করেছে যার বৈধতার সময়সীমা এত বেশী যে বিশ্বাসযোগ্য নয়।</translation>
<translation id="7087282848513945231">দেশ</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/> এ অনুবাদ ব্যর্থ হয়েছে৷</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" /> এ অনুবাদ ব্যর্থ হয়েছে৷</translation>
<translation id="7139724024395191329">এমিরেট</translation>
+<translation id="7179921470347911571">এখনই পুনঃলঞ্চ করুন</translation>
<translation id="7180611975245234373">রিফ্রেশ করুন</translation>
<translation id="7182878459783632708">কোন নীতি সেট করা নেই</translation>
-<translation id="7186367841673660872">এই পৃষ্ঠাটি<ph name="ORIGINAL_LANGUAGE"/>থেকে<ph name="LANGUAGE_LANGUAGE"/>তে অনুবাদ করা হয়েছে</translation>
+<translation id="7186367841673660872">এই পৃষ্ঠাটি<ph name="ORIGINAL_LANGUAGE" />থেকে<ph name="LANGUAGE_LANGUAGE" />তে অনুবাদ করা হয়েছে</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531"><ph name="SITE_NAME"/>-এ <ph name="SEARCH_TERMS"/> অনুসন্ধান করুন</translation>
+<translation id="7208899522964477531"><ph name="SITE_NAME" />-এ <ph name="SEARCH_TERMS" /> অনুসন্ধান করুন</translation>
+<translation id="725866823122871198"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> এ একটি ব্যক্তিগত সংযোগ স্থাপন করা যায়নি কারণ আপনার কম্পিউটারের তারিখ এবং সময় (<ph name="DATE_AND_TIME" />) সঠিক নয়৷</translation>
<translation id="7275334191706090484">পরিচালিত বুকমার্কগুলি</translation>
<translation id="7298195798382681320">প্রস্তাবিত</translation>
<translation id="7334320624316649418">&amp;পুনর্বিন্যাসকে পুনরায় করুন</translation>
@@ -210,31 +264,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">বাধ্যতামূলক</translation>
<translation id="7542995811387359312">স্বয়ংক্রিয় ক্রেডিট কার্ড পূরণটি অক্ষম রয়েছে কারণ এই ফর্মটি কোনও সুরক্ষিত সংযোগ ব্যবহার করে না৷</translation>
-<translation id="7568593326407688803">এই পৃষ্ঠাটি<ph name="ORIGINAL_LANGUAGE"/>ভাষাতে আছে আপনি কি এটিকে অনুবাদ করতে চাইবেন?</translation>
+<translation id="7567204685887185387">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্র প্রতারণাপূর্ণভাবে ইস্যু করা হয়ে থাকতে পারে। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
+<translation id="7568593326407688803">এই পৃষ্ঠাটি<ph name="ORIGINAL_LANGUAGE" />ভাষাতে আছে আপনি কি এটিকে অনুবাদ করতে চাইবেন?</translation>
<translation id="7569952961197462199">Chrome থেকে ক্রেডিট কার্ড সরাবেন?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/> কখনও অনুবাদ করবেন না</translation>
-<translation id="7610193165460212391">সীমার বাইরে মান <ph name="VALUE"/>৷</translation>
+<translation id="7592362899630581445">সার্ভারের শংসাপত্র, নামের সীমাবদ্ধতাগুলি লঙ্ঘন করে৷</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" /> কখনও অনুবাদ করবেন না</translation>
+<translation id="7610193165460212391">সীমার বাইরে মান <ph name="VALUE" />৷</translation>
+<translation id="7674629440242451245">Chrome এর নতুন দুর্দান্ত বৈশিষ্ট্যগুলিতে আগ্রহী? chrome.com/dev এ আমাদের ডেভ চ্যানেল ব্যবহার করে দেখুন৷</translation>
<translation id="7752995774971033316">অপরিচালিত</translation>
+<translation id="7761701407923456692">সার্ভারের শংসাপত্র URL-এর সাথে মেলে না৷</translation>
<translation id="777702478322588152">জেলা</translation>
<translation id="7791543448312431591">যুক্ত করুন</translation>
<translation id="7805768142964895445">স্থিতি</translation>
<translation id="7813600968533626083">Chrome থেকে ফর্ম প্রস্তাবনা সরাবেন?</translation>
<translation id="7887683347370398519">আপনার CVC পরীক্ষা করুন এবং আবার চেষ্টা করুন</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">সার্ভারের শংসাপত্র এখনও কার্যকর নয়.</translation>
<translation id="7956713633345437162">মোবাইল বুকমার্ক</translation>
<translation id="7961015016161918242">কখনই নয়</translation>
<translation id="7977590112176369853">&lt;ক্যোয়ারী লিখুন&gt;</translation>
-<translation id="7983301409776629893">সর্বদা <ph name="ORIGINAL_LANGUAGE"/>-কে <ph name="TARGET_LANGUAGE"/>-তে অনুবাদ করুন</translation>
+<translation id="7983301409776629893">সর্বদা <ph name="ORIGINAL_LANGUAGE" />-কে <ph name="TARGET_LANGUAGE" />-তে অনুবাদ করুন</translation>
<translation id="7988324688042446538">ডেস্কটপ বুকমার্ক</translation>
<translation id="7995512525968007366">নির্দিষ্ট করে উল্লেখ করা নেই</translation>
-<translation id="8034522405403831421">এই পৃষ্ঠাটি <ph name="SOURCE_LANGUAGE"/> ভাষায় রয়েছে৷ এটিকে <ph name="TARGET_LANGUAGE"/> ভাষায় অনুবাদ করবেন?</translation>
+<translation id="8003882219468422867">এন্টারপ্রাইজ ওভাররাইড</translation>
+<translation id="8034522405403831421">এই পৃষ্ঠাটি <ph name="SOURCE_LANGUAGE" /> ভাষায় রয়েছে৷ এটিকে <ph name="TARGET_LANGUAGE" /> ভাষায় অনুবাদ করবেন?</translation>
<translation id="8088680233425245692">নিবন্ধ দেখতে ব্যর্থ হয়েছে৷</translation>
<translation id="8091372947890762290">সার্ভারে সক্রিয়করণ বাকি আছে</translation>
<translation id="8194797478851900357">&amp;সরানোকে পূর্বাবস্থায় ফেরান</translation>
-<translation id="8201077131113104583">&quot;<ph name="EXTENSION_ID"/>&quot; ID যুক্ত এক্সটেনশানের অবৈধ আপডেট URL।</translation>
+<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" ID যুক্ত এক্সটেনশানের অবৈধ আপডেট URL।</translation>
<translation id="8208216423136871611">সংরক্ষণ করবেন না</translation>
<translation id="8218327578424803826">নির্ধারিত অবস্থান:</translation>
<translation id="8249320324621329438">সর্বশেষ প্রাপ্ত করেছে:</translation>
+<translation id="8294431847097064396">উৎস</translation>
<translation id="8308427013383895095">নেটওয়ার্ক সংযোগে কোন সমস্যা হওয়ার কারণে অনুবাদ ব্যর্থ হয়েছে৷</translation>
<translation id="8311778656528046050">আপনি কি এই পৃষ্ঠাটি পুনঃলোড করার ব্যাপারে নিশ্চিত?</translation>
<translation id="8349305172487531364">বুকমার্কস দণ্ড</translation>
@@ -243,25 +304,40 @@
<translation id="8488350697529856933">এতে প্রয়োগ হয়</translation>
<translation id="8530504477309582336">এই ধরনের কার্ড Google Payments দ্বারা সমর্থিত নয়৷ দয়া করে একটি আলাদা কার্ড নির্বাচন করুন৷</translation>
<translation id="8553075262323480129">পৃষ্ঠার ভাষা নির্ধারণ না করতে পারার কারণে অনুবাদ ব্যর্থ হয়েছে৷</translation>
-<translation id="8571890674111243710">পৃষ্ঠাটি<ph name="LANGUAGE"/>তে অনুবাদ করুন...</translation>
+<translation id="8559762987265718583"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> এ একটি ব্যক্তিগত সংযোগ স্থাপন করা যায়নি কারণ আপনার ডিভাইসের তারিখ এবং সময় (<ph name="DATE_AND_TIME" />) সঠিক নয়৷</translation>
+<translation id="8571890674111243710">পৃষ্ঠাটি<ph name="LANGUAGE" />তে অনুবাদ করুন...</translation>
+<translation id="8647750283161643317">সবগুলিকে ডিফল্টে পুনরায় সেট করুন</translation>
<translation id="8713130696108419660">খারাপ ইনিশিয়াল স্বাক্ষর</translation>
<translation id="8725066075913043281">আবার চেষ্টা করুন</translation>
+<translation id="8738058698779197622">নিরাপদ নেটওয়ার্ক সংযোগ স্থাপন করতে আপনার ঘড়িকে সঠিকভাবে সেট করতে হবে৷ নিরাপদ সংযোগ স্থাপন করার জন্য নিজেদের সনাক্ত করার জন্য ওয়েবসাইটগুলি যে শংসাপত্রগুলি ব্যবহার করে, সেগুলি শুধুমাত্র নির্দিষ্ট সময়ের জন্য বৈধ থাকে৷ যেহেতু আপনার ডিভাইসের ঘড়িটি ভুল, সেই জন্য Chromium সঠিকভাবে শংসাপত্রগুলি পরীক্ষা করতে পারে না৷</translation>
<translation id="8790007591277257123">&amp;মুছে ফেলাকে পুনরায় করুন</translation>
<translation id="8804164990146287819">গোপনীয়তা নীতি</translation>
+<translation id="8820817407110198400">বুকমার্কস</translation>
<translation id="8824019021993735287">Chrome এই মুহূর্তে আপনার কার্ড যাচাই করতে অক্ষম হয়েছে৷ অনুগ্রহ করে পরে আবার চেষ্টা করুন৷</translation>
<translation id="8834246243508017242">পরিচিতিগুলি ব্যবহার করে স্বতঃপূর্ণ সক্ষম করুন...</translation>
<translation id="883848425547221593">অন্যান্য বুকমার্ক</translation>
+<translation id="884923133447025588">কোন প্রত্যাহার নির্মাণকৌশল পাওয়া যায় নি৷</translation>
<translation id="8866481888320382733">নীতি সেটিংস বিশ্লেষণ করার সময় ত্রুটি</translation>
<translation id="8876793034577346603">নেটওয়ার্ক কনফিগারেশন বিশ্লেষণ করতে ব্যর্থ হয়েছে৷</translation>
<translation id="8891727572606052622">প্রক্সি মোড অবৈধ৷</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/>আদেশটি <ph name="SEARCH_TERMS"/>চালনা করুন</translation>
+<translation id="889901481107108152">দুঃখিত, এই গবেষণা আপনার প্ল্যাটফর্মে উপলব্ধ নেই৷</translation>
+<translation id="8903921497873541725">জুম বাড়ান</translation>
+<translation id="8932102934695377596">আপনার ঘড়ির সময় পিছিয়ে রয়েছে</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" />আদেশটি <ph name="SEARCH_TERMS" />চালনা করুন</translation>
+<translation id="8971063699422889582">সার্ভারের শংসাপত্রের মেয়াদ ফুরিয়েছে৷</translation>
<translation id="8988760548304185580">আপনার কার্ডের পিছনে থাকা ৩ সংখ্যার CVC এবং মেয়াদ শেষের তারিখ লিখুন</translation>
-<translation id="9020542370529661692">এই পৃষ্ঠাটি <ph name="TARGET_LANGUAGE"/> এ অনুবাদ করা হয়েছে</translation>
+<translation id="901974403500617787">যে ফ্ল্যাগগুলি সমস্ত সিস্টেম জুড়ে প্রয়োগ করা হয় সেগুলি শুধুমাত্র মালিকের দ্বারা সেট করা যেতে পারে: <ph name="OWNER_EMAIL" />৷</translation>
+<translation id="9020542370529661692">এই পৃষ্ঠাটি <ph name="TARGET_LANGUAGE" /> এ অনুবাদ করা হয়েছে</translation>
+<translation id="9049981332609050619">আপনি <ph name="DOMAIN" />-এ পৌছানোর প্রয়াস করছেন, কিন্তু সার্ভার একটি অবৈধ শংসাপত্র উপস্থাপন করেছে|</translation>
<translation id="9125941078353557812">আপনার কার্ডের পিছনে থাকা ৩ সংখ্যার CVC লিখুন</translation>
<translation id="9137013805542155359">প্রকৃত রূপ দেখান</translation>
<translation id="9148507642005240123">&amp;সম্পাদনাকে পূর্বাবস্থায় ফেরান</translation>
<translation id="9154176715500758432">এই পৃষ্ঠাতে থাকুন</translation>
<translation id="9170848237812810038">&amp;পূর্বাবস্থায় ফিরুন</translation>
+<translation id="917450738466192189">সার্ভারের শংসাপত্র অকার্যকর৷</translation>
+<translation id="9187827965378254003">ওহো, দেখে মনে হচ্ছে বর্তমানে কোনও পরীক্ষানিরীক্ষা উপলভ্য নেই৷</translation>
<translation id="9207861905230894330">নিবন্ধ যোগ করতে ব্যর্থ হয়েছে৷</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ফর্ম সাফ করুন</translation>
+<translation id="988159990683914416">বিকাশকারী বিল্ড</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ca.xtb b/chromium/components/strings/components_strings_ca.xtb
index 1e38a72d387..c988e282f7c 100644
--- a/chromium/components/strings/components_strings_ca.xtb
+++ b/chromium/components/strings/components_strings_ca.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ca">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ca">
+<translation id="1032854598605920125">Gira en el sentit de les agulles del rellotge</translation>
<translation id="1055184225775184556">&amp;Desfés l'addició</translation>
<translation id="106701514854093668">Adreces d'interès d'escriptori</translation>
-<translation id="1103523840287552314">Tradueix sempre l'idioma <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Ajusta a l'amplada</translation>
+<translation id="1103523840287552314">Tradueix sempre l'idioma <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Desfés el canvi d'ordre</translation>
<translation id="111844081046043029">Estàs segur que vols marxar d'aquesta pàgina?</translation>
<translation id="112840717907525620">La memòria cau de la política està en bon estat</translation>
<translation id="1132774398110320017">Configuració d'Emplenament automàtic de Chrome...</translation>
-<translation id="1152921474424827756">Accediu a una <ph name="BEGIN_LINK"/>còpia emmagatzemada a la memòria cau<ph name="END_LINK"/> de la pàgina <ph name="URL"/>.</translation>
+<translation id="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="1152921474424827756">Accediu a una <ph name="BEGIN_LINK" />còpia emmagatzemada a la memòria cau<ph name="END_LINK" /> de la pàgina <ph name="URL" />.</translation>
+<translation id="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="1227224963052638717">Política desconeguda.</translation>
<translation id="1227633850867390598">Amaga el valor</translation>
<translation id="1228893227497259893">Identificador d'entitat incorrecte</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Domini d'inscripció:</translation>
<translation id="1344588688991793829">Configuració d'Emplenament automàtic de Chromium...</translation>
<translation id="1426410128494586442">Sí</translation>
+<translation id="1430915738399379752">Impressió</translation>
<translation id="1455235771979731432">S'ha produït un problema en verificar la targeta. Comproveu la connexió a Internet i torneu-ho a provar.</translation>
<translation id="1491151370853475546">Torna a carregar aquesta pàgina</translation>
<translation id="1549470594296187301">Heu d'activar el JavaScript per utilitzar aquesta funció.</translation>
-<translation id="1639239467298939599">S'està carregant</translation>
<translation id="1640180200866533862">Polítiques d'usuari</translation>
<translation id="1644184664548287040">La configuració de la xarxa no és vàlida i no s'ha pogut importar.</translation>
-<translation id="1693754753824026215">La pàgina de <ph name="SITE"/> diu:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Aquest servidor no ha pogut demostrar que sigui <ph name="DOMAIN" /> perquè el seu certificat de seguretat va caducar ahir. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió. Actualment, el rellotge del vostre ordinador està configurat amb la data <ph name="CURRENT_DATE" />. És correcta? Si no ho és, corregiu el rellotge del sistema i, a continuació, actualitzeu aquesta pàgina.}other{Aquest servidor no ha pogut demostrar que sigui <ph name="DOMAIN" /> perquè el seu certificat va caducar fa # dies. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió. Actualment, el rellotge del vostre ordinador està configurat amb la data <ph name="CURRENT_DATE" />. És correcta? Si no ho és, corregiu el rellotge del sistema i, a continuació, actualitzeu aquesta pàgina.}}</translation>
+<translation id="168841957122794586">El certificat de servidor conté una clau criptogràfica dèbil.</translation>
+<translation id="1693754753824026215">La pàgina de <ph name="SITE" /> diu:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Aquest servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè el sistema operatiu del vostre dispositiu considera que el seu certificat de seguretat no és de confiança. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.</translation>
<translation id="1821930232296380041">Sol·licitud o paràmetres de la sol·licitud no vàlids</translation>
-<translation id="1853748787962613237">No s'ha pogut mostrar l'article.</translation>
<translation id="1871208020102129563">El servidor intermediari està configurat perquè utilitzi servidors intermediaris fixos, en lloc d'un URL d'script .pac.</translation>
-<translation id="1875753206475436906">tipus heurístic: <ph name="HEURISTIC_TYPE"/>
- tipus de servidor: <ph name="SERVER_TYPE"/>
- signatura del camp: <ph name="FIELD_SIGNATURE"/>
- signatura del formulari: <ph name="FORM_SIGNATURE"/>
- identificador de l'experiment: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Vés a <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Adreces d'interès de <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Vés a <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Adreces d'interès de <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Error de serialització</translation>
+<translation id="1974060860693918893">Configuració avançada</translation>
<translation id="2025186561304664664">El servidor intermediari està definit perquè es configuri automàticament.</translation>
<translation id="2025623846716345241">Confirmació de la càrrega nova</translation>
-<translation id="2030481566774242610">Volíeu dir <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Volíeu dir <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Codi postal</translation>
<translation id="20817612488360358">S'ha definit la configuració del servidor intermediari del sistema perquè es pugui utilitzar, però també s'ha especificat una configuració del servidor intermediari explícita.</translation>
<translation id="2094505752054353250">Els dominis no coincideixen.</translation>
<translation id="2096368010154057602">Departament</translation>
<translation id="2113977810652731515">Targeta</translation>
-<translation id="2114841414352855701">S'ha ignorat perquè <ph name="POLICY_NAME"/> l'ha substituït.</translation>
+<translation id="2114841414352855701">S'ha ignorat perquè <ph name="POLICY_NAME" /> l'ha substituït.</translation>
+<translation id="2128531968068887769">Client nadiu</translation>
<translation id="213826338245044447">Adreces d'interès per a mòbils</translation>
+<translation id="2171101176734966184">Heu provat d'accedir a <ph name="DOMAIN" />, però el servidor ha presentat un certificat signat mitjançant un algoritme de signatura dèbil. Això indica que les credencials de seguretat que ha presentat el servidor podrien haver estat falsificades i que és possible que el servidor no sigui el que esperàveu (és possible que us estigueu comunicant amb un atacant).</translation>
<translation id="2181821976797666341">Polítiques</translation>
<translation id="2212735316055980242">No es troba la política</translation>
<translation id="2213606439339815911">S'estan recuperant les entrades...</translation>
<translation id="225207911366869382">El valor d'aquesta política és obsolet.</translation>
<translation id="2262243747453050782">Error d'HTTP</translation>
-<translation id="2270192940992995399">No s'ha pogut trobar l'article.</translation>
-<translation id="2328300916057834155">S'ha ignorat l'adreça d'interès no vàlida a l'índex <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Experiments no disponibles</translation>
+<translation id="229702904922032456">Ha caducat un certificat arrel o intermedi.</translation>
+<translation id="2328300916057834155">S'ha ignorat l'adreça d'interès no vàlida a l'índex <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Altres adreces d'interès</translation>
<translation id="2359808026110333948">Continua</translation>
<translation id="2367567093518048410">Nivell</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="2396249848217231973">&amp;Desfés la supressió</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="2455981314101692989">Aquesta pàgina web ha desactivat l'emplenament automàtic per a aquest formulari.</translation>
<translation id="2479410451996844060">URL de cerca no vàlid.</translation>
+<translation id="2491120439723279231">El certificat del servidor conté errors.</translation>
<translation id="2495083838625180221">Analitzador JSON</translation>
<translation id="2498091847651709837">Escaneja una targeta nova</translation>
<translation id="2556876185419854533">&amp;Desfés la modificació</translation>
-<translation id="2581221116934462656">La propera vegada, voleu que <ph name="PRODUCT_NAME"/> ofereixi la traducció de les pàgines escrites en <ph name="LANGUAGE_NAME"/> d'aquest lloc?</translation>
+<translation id="2581221116934462656">La propera vegada, voleu que <ph name="PRODUCT_NAME" /> ofereixi la traducció de les pàgines escrites en <ph name="LANGUAGE_NAME" /> d'aquest lloc?</translation>
<translation id="2587841377698384444">Identificador de l'API de directoris:</translation>
<translation id="2597378329261239068">Aquest document està protegit mitjançant contrasenya. Introduïu una contrasenya.</translation>
+<translation id="2625385379895617796">El rellotge està avançat</translation>
<translation id="2639739919103226564">Estat:</translation>
+<translation id="2653659639078652383">Envia</translation>
<translation id="2704283930420550640">El valor no coincideix amb el format.</translation>
<translation id="2721148159707890343">Sol·licitud realitzada correctament</translation>
+<translation id="2728127805433021124">El certificat del servidor està signat mitjançant un algoritme de signatura dèbil.</translation>
<translation id="2774256287122201187">Podeu continuar. Si accediu a la pàgina, no es tornarà a mostrar aquest advertiment fins d'aquí a cinc minuts.</translation>
<translation id="277499241957683684">Falta el registre del dispositiu</translation>
<translation id="2835170189407361413">Esborra el formulari</translation>
-<translation id="2855922900409897335">Verifica la targeta <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Verifica la targeta <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Aquest servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè el seu certificat de seguretat ha caducat. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió. Actualment, el rellotge de l'ordinador està definit com a <ph name="CURRENT_TIME" />. Creieu que és correcte? Si no és així, corregiu el rellotge del sistema i actualitzeu aquesta pàgina.</translation>
+<translation id="2922350208395188000">No es pot comprovar el certificat del servidor.</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="2958431318199492670">La configuració de la xarxa no compleix l'estàndard ONC. Pot ser que algunes opcions de configuració no s'hagin importat.</translation>
<translation id="2972581237482394796">&amp;Refés</translation>
-<translation id="3010559122411665027">Entrada de llista &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Entrada de llista "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Tipus de política incorrecte</translation>
<translation id="3105172416063519923">Identificador de l'element:</translation>
<translation id="3145945101586104090">No s'ha pogut descodificar la resposta</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Illa</translation>
<translation id="3219579145727097045">Introduïu la data de caducitat i el CVC de quatre dígits que trobareu a la part davantera de la targeta</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="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="3228969707346345236">S'ha produït un error en fer la traducció perquè la pàgina ja està en <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Desfés el canvi d'ordre</translation>
+<translation id="3286538390144397061">Reinicia ara</translation>
<translation id="333371639341676808">Evita que aquesta pàgina creï diàlegs addicionals.</translation>
-<translation id="3369366829301677151">Actualitzeu i verifiqueu <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">configuració</translation>
+<translation id="3369192424181595722">Error de rellotge</translation>
+<translation id="3369366829301677151">Actualitzeu i verifiqueu <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">No administrat</translation>
<translation id="3377188786107721145">S'ha produït un error en analitzar la política</translation>
<translation id="3380365263193509176">Error desconegut</translation>
<translation id="3380864720620200369">Identificador de client:</translation>
<translation id="3427342743765426898">&amp;Refés la modificació</translation>
+<translation id="3435896845095436175">Activa</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Obtén l'interval:</translation>
+<translation id="3462200631372590220">Amaga la informació avançada</translation>
+<translation id="3528171143076753409">El certificat del servidor no és de confiança.</translation>
<translation id="3542684924769048008">Utilitzar la contrasenya per a:</translation>
<translation id="3583757800736429874">&amp;Refés el moviment</translation>
<translation id="3623476034248543066">Mostra el valor</translation>
+<translation id="3648607100222897006">Aquestes funcions experimentals poden canviar, trencar-se o desaparèixer en qualsevol moment. No donem cap garantia sobre què pot passar si activeu algun d'aquests experiments, i fins i tot el vostre navegador es podria fregir de sobte. Bromes a part,és possible que el vostre navegador suprimeixi totes les vostres dades, o bé la seguretat i la privadesa poden estar compromeses de maneres inesperades. Qualsevol experiment que activeu s'activaran per a tots els usuaris d'aquest navegador. Continueu amb precaució.</translation>
<translation id="3650584904733503804">Validació correcta</translation>
<translation id="370665806235115550">S'està carregant...</translation>
<translation id="3712624925041724820">Llicències exhaurides</translation>
<translation id="3739623965217189342">Enllaç que heu copiat</translation>
<translation id="375403751935624634">S'ha produït un error en el procés de traducció a causa d'un error del servidor.</translation>
<translation id="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>
<translation id="3885155851504623709">Diòcesi</translation>
<translation id="3934680773876859118">No es pot carregar el document en format PDF</translation>
<translation id="3963721102035795474">Mode de lector</translation>
<translation id="4030383055268325496">&amp;Desfés l'addició</translation>
-<translation id="4058922952496707368">Tecla &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ADVERTIMENT</translation>
+<translation id="4058922952496707368">Tecla "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">La configuració del servidor intermediari s'ha definit perquè utilitzi un URL d'script .pac, en lloc de servidors intermedis fixos.</translation>
<translation id="409504436206021213">No la tornis a carregar</translation>
<translation id="4103249731201008433">El número de sèrie del dispositiu no és vàlid</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Signatura errònia</translation>
<translation id="4269787794583293679">(Sense nom d'usuari)</translation>
<translation id="4300246636397505754">Suggeriments per als responsables</translation>
-<translation id="4372948949327679948">Valor <ph name="VALUE_TYPE"/> esperat.</translation>
+<translation id="4325863107915753736">No s'ha pogut trobar l'article</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="4394049700291259645">Desactiva</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="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="4506176782989081258">Error de validació: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Error de validació: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Voleu suprimir l'adreça de Chrome?</translation>
<translation id="4594403342090139922">&amp;Desfés la supressió</translation>
<translation id="4607653538520819196">Economitzador de dades no pot enviar aquesta pàgina a un servidor intermediari.</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="4726672564094551039">Torna a carregar les polítiques</translation>
+<translation id="4728558894243024398">Plataforma</translation>
+<translation id="4771973620359291008">S'ha produït un error desconegut.</translation>
<translation id="4800132727771399293">Comproveu la data de caducitat i el CVC i torneu-ho a provar</translation>
<translation id="4813512666221746211">Error de xarxa</translation>
+<translation id="4816492930507672669">Ajusta a la mida de la pàgina</translation>
<translation id="4850886885716139402">Visualització</translation>
-<translation id="4923417429809017348">Aquesta pàgina s'ha traduït des d'un idioma desconegut a: <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Aquesta pàgina s'ha traduït des d'un idioma desconegut a: <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">S'ha d'especificar.</translation>
<translation id="4968547170521245791">No es pot utilitzar el servidor intermediari</translation>
-<translation id="498957508165411911">Voleu traduir de <ph name="ORIGINAL_LANGUAGE"/> a <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Voleu traduir de <ph name="ORIGINAL_LANGUAGE" /> a <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">L'emmagatzematge de la còpia de seguretat està en mal estat</translation>
<translation id="5031870354684148875">Sobre el Traductor de Google</translation>
+<translation id="5045550434625856497">Contrasenya incorrecta</translation>
+<translation id="5087286274860437796">En aquest moment el certificat del servidor no és vàlid.</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="5145883236150621069">Hi ha un codi d'error en la resposta a la política</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="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="5199729219167945352">Experiments</translation>
+<translation id="5251803541071282808">Núvol</translation>
<translation id="5295309862264981122">Confirma la navegació</translation>
<translation id="5299298092464848405">S'ha produït un error en analitzar la política</translation>
+<translation id="5316812925700871227">Gira en el sentit contrari a les agulles del rellotge</translation>
<translation id="5317780077021120954">Desa</translation>
<translation id="536296301121032821">No s'ha pogut emmagatzemar la configuració de la política</translation>
-<translation id="5439770059721715174">Error de validació de l'esquema a &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Error de validació de l'esquema a "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Marca de temps de la política incorrecta</translation>
<translation id="5470861586879999274">&amp;Refés la modificació</translation>
<translation id="5509780412636533143">Adreces d'interès gestionades</translation>
<translation id="5523118979700054094">Nom de la política</translation>
<translation id="552553974213252141">S'ha extret correctament el text?</translation>
<translation id="5540224163453853">No s'ha pogut trobar l'article sol·licitat.</translation>
+<translation id="5556459405103347317">Torna a carregar</translation>
<translation id="5565735124758917034">Actiu</translation>
<translation id="560412284261940334">Gestió no compatible</translation>
<translation id="5629630648637658800">No s'ha pogut carregar la configuració de la política</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Usuari actual</translation>
<translation id="5813119285467412249">&amp;Refés l'addició</translation>
<translation id="5872918882028971132">Suggeriments per als responsables</translation>
-<translation id="587701087903783706">Tanca la visualització adaptada per a mòbils</translation>
<translation id="59107663811261420">Google Payments no admet aquest tipus de targeta per a aquest comerciant. Seleccioneu-ne una altra.</translation>
+<translation id="5975083100439434680">Redueix</translation>
<translation id="5989320800837274978">No s'especifiquen servidors intermediaris ni URL d'script .pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Tanca</translation>
+<translation id="6060685159320643512">Compte! Aquests experiments mosseguen</translation>
+<translation id="6151417162996330722">El període de validesa del certificat del servidor és massa gran.</translation>
<translation id="6154808779448689242">El testimoni de la política que s'ha retornat no coincideix amb el testimoni actual</translation>
<translation id="6165508094623778733">Més informació</translation>
<translation id="6259156558325130047">&amp;Refés el canvi d'ordre</translation>
-<translation id="6263376278284652872">Adreces d'interès de <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Adreces d'interès de <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Codi postal</translation>
<translation id="6337534724793800597">Filtra les polítiques pel nom</translation>
+<translation id="6387478394221739770">Esteu interessat en les funcions de Chrome noves i interessants? Proveu el nostre canal beta a la pàgina chrome.com/beta.</translation>
+<translation id="6426993025560594914">Tots els experiments estan disponibles a la vostra plataforma.</translation>
<translation id="6445051938772793705">País</translation>
<translation id="6458467102616083041">S'ha ignorat perquè la política ha desactivat la cerca predeterminada.</translation>
<translation id="647261751007945333">Polítiques de dispositius</translation>
<translation id="6512448926095770873">Abandona aquesta pàgina</translation>
<translation id="6529602333819889595">&amp;Refés la supressió</translation>
<translation id="6550675742724504774">Opcions</translation>
-<translation id="6597614308054261376">Esteu intentant accedir a <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. En aquest moment Economitzador de dades no pot enviar aquesta pàgina a un servidor intermediari.</translation>
-<translation id="6628463337424475685">Cerca de <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Esteu intentant accedir a <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. En aquest moment Economitzador de dades no pot enviar aquesta pàgina a un servidor intermediari.</translation>
+<translation id="6628463337424475685">Cerca de <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Aquesta política ha quedat obsoleta.</translation>
<translation id="6646897916597483132">Introduïu el CVC de quatre dígits que trobareu a la part davantera de la targeta</translation>
+<translation id="674375294223700098">Error de certificat del servidor desconegut.</translation>
<translation id="6753269504797312559">Valor de la política</translation>
<translation id="6831043979455480757">Tradueix</translation>
<translation id="6839929833149231406">Àrea</translation>
<translation id="6874604403660855544">&amp;Refés l'addició</translation>
<translation id="6891596781022320156">No s'admet el nivell de la política.</translation>
<translation id="6915804003454593391">Usuari:</translation>
+<translation id="6957887021205513506">Sembla que el certificat del servidor és una falsificació.</translation>
<translation id="6965382102122355670">D'acord</translation>
<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="6980028882292583085">Alerta de JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Heu provat de connectar-vos a <ph name="DOMAIN" />, però el servidor ha presentat un certificat amb un període de validesa massa gran per poder confiar-hi.</translation>
<translation id="7087282848513945231">Comptat</translation>
-<translation id="7108649287766967076">La traducció a <ph name="TARGET_LANGUAGE"/> ha fallat.</translation>
+<translation id="7108649287766967076">La traducció a <ph name="TARGET_LANGUAGE" /> ha fallat.</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7179921470347911571">Torna'l a iniciar ara</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="7186367841673660872">Aquesta pàgina s'ha traduït de:<ph name="ORIGINAL_LANGUAGE" />a:<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Cerca <ph name="SITE_NAME"/> per a <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Cerca <ph name="SITE_NAME" /> per a <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">No s'ha pogut establir una connexió privada amb <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perquè la data i l'hora (<ph name="DATE_AND_TIME" />) de l'ordinador no són correctes.</translation>
<translation id="7275334191706090484">Adreces d'interès gestionades</translation>
<translation id="7298195798382681320">Recomanada</translation>
<translation id="7334320624316649418">&amp;Refés el canvi d'ordre</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obligatòria</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="7568593326407688803">Aquesta pàgina està en<ph name="ORIGINAL_LANGUAGE"/>Voleu traduir-la?</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="7568593326407688803">Aquesta pàgina està en<ph name="ORIGINAL_LANGUAGE" />Voleu traduir-la?</translation>
<translation id="7569952961197462199">Voleu suprimir la targeta de crèdit de Chrome?</translation>
-<translation id="7600965453749440009">No tradueixis mai de: <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">El valor es troba fora de l'interval <ph name="VALUE"/> .</translation>
+<translation id="7592362899630581445">El certificat del servidor incompleix les restriccions de nom.</translation>
+<translation id="7600965453749440009">No tradueixis mai de: <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">El valor es troba fora de l'interval <ph name="VALUE" /> .</translation>
+<translation id="7674629440242451245">Esteu interessat en les funcions de Chrome noves i interessants? Proveu el nostre canal per a desenvolupadors a la pàgina chrome.com/dev.</translation>
<translation id="7752995774971033316">Sense gestionar</translation>
+<translation id="7761701407923456692">El certificat del servidor no coincideix amb l'URL.</translation>
<translation id="777702478322588152">Prefectura</translation>
<translation id="7791543448312431591">Afegeix</translation>
<translation id="7805768142964895445">Estat</translation>
<translation id="7813600968533626083">Voleu suprimir el suggeriment de formulari de Chrome?</translation>
<translation id="7887683347370398519">Comproveu el CVC i torneu-ho a provar</translation>
<translation id="7935318582918952113">Destil·lador DOM</translation>
+<translation id="7938958445268990899">El certificat del servidor encara no és vàlid.</translation>
<translation id="7956713633345437162">Adreces d'interès per a mòbils</translation>
<translation id="7961015016161918242">Mai</translation>
<translation id="7977590112176369853">&lt;introdueix la consulta&gt;</translation>
-<translation id="7983301409776629893">Tradueix sempre de: <ph name="ORIGINAL_LANGUAGE"/> a: <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Tradueix sempre de: <ph name="ORIGINAL_LANGUAGE" /> a: <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Adreces d'interès d'escriptori</translation>
<translation id="7995512525968007366">No especificat</translation>
-<translation id="8034522405403831421">Aquesta pàgina està escrita en <ph name="SOURCE_LANGUAGE"/>. Voleu traduir-la a <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">De l'empresa (no es pot substituir)</translation>
+<translation id="8034522405403831421">Aquesta pàgina està escrita en <ph name="SOURCE_LANGUAGE" />. Voleu traduir-la a <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">No s'ha pogut consultar l'article.</translation>
<translation id="8091372947890762290">L'activació està pendent al servidor</translation>
<translation id="8194797478851900357">&amp;Desfés el moviment</translation>
-<translation id="8201077131113104583">L'URL d'actualització per a l'extensió amb identificador &quot;<ph name="EXTENSION_ID"/>&quot; no és vàlid.</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="8208216423136871611">No desis</translation>
<translation id="8218327578424803826">Ubicació assignada:</translation>
<translation id="8249320324621329438">Última obtenció:</translation>
+<translation id="8294431847097064396">Font</translation>
<translation id="8308427013383895095">No s'ha pogut executar la traducció a causa d'un problema amb la connexió de xarxa.</translation>
<translation id="8311778656528046050">Esteu segur que voleu tornar a carregar aquesta pàgina?</translation>
<translation id="8349305172487531364">Barra d'adreces d'interès</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Objectiu d'aplicació</translation>
<translation id="8530504477309582336">Google Payments no admet aquest tipus de targeta. Seleccioneu-ne una altra.</translation>
<translation id="8553075262323480129">S'ha produït un error en fer la traducció perquè no s'ha pogut determinar l'idioma de la pàgina.</translation>
-<translation id="8571890674111243710">S'està traduint la pàgina a l'idioma <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">No es pot establir una connexió privada amb <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perquè la data i l'hora (<ph name="DATE_AND_TIME" />) del dispositiu són incorrectes.</translation>
+<translation id="8571890674111243710">S'està traduint la pàgina a l'idioma <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Restableix-ho tot als valors predeterminats</translation>
<translation id="8713130696108419660">Signatura inicial incorrecta</translation>
<translation id="8725066075913043281">Torna-ho a provar</translation>
+<translation id="8738058698779197622">Per establir una connexió segura, el rellotge ha d'estar ben ajustat, perquè els certificats que els llocs web fan servir per identificar-se només són vàlids per a períodes de temps concrets. Com que el rellotge del dispositiu no està ben ajustat, Chromium no pot verificar aquests certificats.</translation>
<translation id="8790007591277257123">&amp;Refés la supressió</translation>
<translation id="8804164990146287819">Política de privadesa</translation>
+<translation id="8820817407110198400">Adreces d'interès</translation>
<translation id="8824019021993735287">Chrome no ha pogut verificar la vostra targeta. Torneu-ho a provar més tard.</translation>
<translation id="8834246243508017242">Activa l'emplenament automàtic mitjançant els contactes...</translation>
<translation id="883848425547221593">Altres adreces d'interès</translation>
+<translation id="884923133447025588">No s'ha trobat cap mecanisme de revocació.</translation>
<translation id="8866481888320382733">S'ha produït un error en analitzar la configuració de la política</translation>
<translation id="8876793034577346603">No s'ha pogut analitzar la configuració de la xarxa.</translation>
<translation id="8891727572606052622">El mode de servidor intermediari no és vàlid.</translation>
-<translation id="8940229512486821554">Executa l'ordre <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Aquest experiment no està disponible a la vostra plataforma.</translation>
+<translation id="8903921497873541725">Amplia</translation>
+<translation id="8932102934695377596">El rellotge està endarrerit</translation>
+<translation id="8940229512486821554">Executa l'ordre <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">El certificat del servidor ha caducat.</translation>
<translation id="8988760548304185580">Introduïu la data de caducitat i el CVC de tres dígits que trobareu a la part posterior de la targeta</translation>
-<translation id="9020542370529661692">Aquesta pàgina s'ha traduït a <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Les marques que s'apliquen a tot el sistema només les pot definir l'usuari: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Aquesta pàgina s'ha traduït a <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Heu provat d'accedir a <ph name="DOMAIN" />, però el servidor ha presentat un certificat no vàlid.</translation>
<translation id="9125941078353557812">Introduïu el CVC de tres dígits que trobareu a la part posterior de la targeta</translation>
<translation id="9137013805542155359">Mostra l'original</translation>
<translation id="9148507642005240123">&amp;Desfés la modificació</translation>
<translation id="9154176715500758432">Roman en aquesta pàgina</translation>
<translation id="9170848237812810038">&amp;Desfés</translation>
+<translation id="917450738466192189">El certificat del servidor no és vàlid.</translation>
+<translation id="9187827965378254003">I ara! Sembla que no hi ha experiments actuals disponibles.</translation>
<translation id="9207861905230894330">No s'ha pogut afegir l'article.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ESBORRA EL FORMULARI</translation>
+<translation id="988159990683914416">Muntatge del desenvolupador</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_cs.xtb b/chromium/components/strings/components_strings_cs.xtb
index a56a657972a..feb89931b72 100644
--- a/chromium/components/strings/components_strings_cs.xtb
+++ b/chromium/components/strings/components_strings_cs.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="cs">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="cs">
+<translation id="1032854598605920125">Otočit ve směru hodinových ručiček</translation>
<translation id="1055184225775184556">&amp;Vrátit přidání zpět</translation>
<translation id="106701514854093668">Záložky v PC</translation>
-<translation id="1103523840287552314">Vždy překládat jazyk <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Přizpůsobit na šířku</translation>
+<translation id="1103523840287552314">Vždy překládat jazyk <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Vrátit změnu uspořádání zpět</translation>
<translation id="111844081046043029">Jste si jisti, že chcete opustit tuto stránku?</translation>
<translation id="112840717907525620">Mezipaměť zásady je v pořádku</translation>
<translation id="1132774398110320017">Nastavení Automatického vyplňování v prohlížeči Chrome...</translation>
-<translation id="1152921474424827756">Otevřete <ph name="BEGIN_LINK"/>archivovanou kopii<ph name="END_LINK"/> stránky <ph name="URL"/></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="1152921474424827756">Otevřete <ph name="BEGIN_LINK" />archivovanou kopii<ph name="END_LINK" /> stránky <ph name="URL" /></translation>
+<translation id="121201262018556460">Pokusili jste se přejít na web <ph name="DOMAIN" />, server však předložil certifikát obsahující slabý klíč. Útočník možná prolomil soukromý klíč a může se jednat o jiný server, než předpokládáte (můžete komunikovat s útočníkem).</translation>
<translation id="1227224963052638717">Neznámá zásada.</translation>
<translation id="1227633850867390598">Skrýt hodnotu</translation>
<translation id="1228893227497259893">Nesprávný identifikátor subjektu</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Doména registrace:</translation>
<translation id="1344588688991793829">Nastavení Automatického vyplňování v prohlížeči Chromium...</translation>
<translation id="1426410128494586442">Ano</translation>
+<translation id="1430915738399379752">Tisk</translation>
<translation id="1455235771979731432">Při ověřování vaší karty došlo k problému. Zkontrolujte připojení k internetu a zkuste to znovu.</translation>
<translation id="1491151370853475546">Načíst tuto stránku znovu</translation>
<translation id="1549470594296187301">Chcete-li tuto funkci použít, musí být aktivován JavaScript.</translation>
-<translation id="1639239467298939599">Načítání</translation>
<translation id="1640180200866533862">Zásady pro uživatele</translation>
<translation id="1644184664548287040">Konfigurace sítě je neplatná a nelze ji importovat.</translation>
-<translation id="1693754753824026215">Stránka na webu <ph name="SITE"/> říká:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Server nedokázal prokázat, že patří doméně <ph name="DOMAIN" />. Platnost jeho bezpečnostního certifikátu včera vypršela. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaše připojení zachytává útočník. Hodiny ve vašem počítači jsou aktuálně nastaveny na <ph name="CURRENT_DATE" />. Je to správně? Pokud ne, měli byste nastavit správné hodiny systému a poté tuto stránku načíst znovu.}few{Server nedokázal prokázat, že patří doméně <ph name="DOMAIN" />. Platnost jeho bezpečnostního certifikátu vypršela před # dny. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaše připojení zachytává útočník. Hodiny ve vašem počítači jsou aktuálně nastaveny na <ph name="CURRENT_DATE" />. Je to správně? Pokud ne, měli byste čas v počítači opravit a poté tuto stránku načíst znovu.}many{Server nedokázal prokázat, že patří doméně <ph name="DOMAIN" />. Platnost jeho bezpečnostního certifikátu vypršela před # dnem. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaše připojení zachytává útočník. Hodiny ve vašem počítači jsou aktuálně nastaveny na <ph name="CURRENT_DATE" />. Je to správně? Pokud ne, měli byste nastavit správné hodiny systému a poté tuto stránku načíst znovu.}other{Server nedokázal prokázat, že patří doméně <ph name="DOMAIN" />. Platnost jeho bezpečnostního certifikátu vypršela před # dny. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaše připojení zachytává útočník. Hodiny ve vašem počítači jsou aktuálně nastaveny na <ph name="CURRENT_DATE" />. Je to správně? Pokud ne, měli byste nastavit správné hodiny systému a poté tuto stránku načíst znovu.}}</translation>
+<translation id="168841957122794586">Certifikát serveru obsahuje slabý kryptografický klíč.</translation>
+<translation id="1693754753824026215">Stránka na webu <ph name="SITE" /> říká:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Server nedokázal prokázat, že patří doméně <ph name="DOMAIN" />. Operační systém vašeho zařízení nedůvěřuje jeho bezpečnostnímu certifikátu. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaše připojení zachytává útočník.</translation>
<translation id="1821930232296380041">Neplatný požadavek nebo parametry požadavku</translation>
-<translation id="1853748787962613237">Zobrazení článku se nezdařilo.</translation>
<translation id="1871208020102129563">Proxy je nastaveno na používání pevně daných serverů proxy, nikoliv adresy URL skriptu PAC.</translation>
-<translation id="1875753206475436906">Typ heuristiky: <ph name="HEURISTIC_TYPE"/>
- Typ serveru: <ph name="SERVER_TYPE"/>
- Podpis pole: <ph name="FIELD_SIGNATURE"/>
- Podpis formuláře: <ph name="FORM_SIGNATURE"/>
- ID experimentu: „<ph name="EXPERIMENT_ID"/>“</translation>
-<translation id="194030505837763158">Přejít na odkaz <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Záložky domény <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Přejít na odkaz <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Záložky domény <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Chyba serializace</translation>
+<translation id="1974060860693918893">Rozšířená nastavení</translation>
<translation id="2025186561304664664">Proxy server je nastaven na automatickou konfiguraci.</translation>
<translation id="2025623846716345241">Potvrdit opětovné načtení</translation>
-<translation id="2030481566774242610">Měli jste na mysli <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Měli jste na mysli <ph name="LINK" />?</translation>
<translation id="2053553514270667976">PSČ</translation>
<translation id="20817612488360358">Jako aktivní jsou nakonfigurována systémová nastavení proxy serveru, je však určena i explicitní konfigurace proxy serveru.</translation>
<translation id="2094505752054353250">Neshoda domén</translation>
<translation id="2096368010154057602">Oddělení</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="2114841414352855701">Zásada ignorována, protože bylo přepsána zásadou <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Mobilní záložky</translation>
+<translation id="2171101176734966184">Pokusili jste se přejít na web <ph name="DOMAIN" />, server však předložil certifikát podepsaný slabým algoritmem. To znamená, že bezpečnostní pověření předložená serverem mohou být falešná a může se jednat o úplně jiný server, než předpokládáte (můžete komunikovat s útočníkem).</translation>
<translation id="2181821976797666341">Zásady</translation>
<translation id="2212735316055980242">Zásada nebyla nalezena</translation>
<translation id="2213606439339815911">Načítání záznamů...</translation>
<translation id="225207911366869382">Tato hodnota již pro tuto zásadu není podporována.</translation>
<translation id="2262243747453050782">Chyba protokolu HTTP</translation>
-<translation id="2270192940992995399">Článek nebyl nalezen.</translation>
-<translation id="2328300916057834155">Byla ignorována neplatná záložka u indexu <ph name="ENTRY_INDEX"/>.</translation>
+<translation id="2282872951544483773">Nedostupné experimenty</translation>
+<translation id="229702904922032456">Platnost kořenového nebo zprostředkujícího certifikátu vypršela.</translation>
+<translation id="2328300916057834155">Byla ignorována neplatná záložka u indexu <ph name="ENTRY_INDEX" />.</translation>
<translation id="2354001756790975382">Ostatní záložky</translation>
<translation id="2359808026110333948">Pokračovat</translation>
<translation id="2367567093518048410">Úroveň</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="2396249848217231973">&amp;Vrátit smazání zpět</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="2455981314101692989">U tohoto formuláře je na dané webové stránce vypnuto automatické vyplňování.</translation>
<translation id="2479410451996844060">Neplatná adresa URL vyhledávání.</translation>
+<translation id="2491120439723279231">Certifikát serveru obsahuje chyby.</translation>
<translation id="2495083838625180221">Analyzátor souborů JSON</translation>
<translation id="2498091847651709837">Naskenovat novou kartu</translation>
<translation id="2556876185419854533">&amp;Vrátit úpravy zpět</translation>
-<translation id="2581221116934462656">Chcete, aby prohlížeč <ph name="PRODUCT_NAME"/> příště pro stránky v jazyce <ph name="LANGUAGE_NAME"/> z tohoto webu nabízel překlad?</translation>
+<translation id="2581221116934462656">Chcete, aby prohlížeč <ph name="PRODUCT_NAME" /> příště pro stránky v jazyce <ph name="LANGUAGE_NAME" /> z tohoto webu nabízel překlad?</translation>
<translation id="2587841377698384444">ID rozhraní Directory API:</translation>
<translation id="2597378329261239068">Tento dokument je chráněn heslem. Zadejte prosím heslo.</translation>
+<translation id="2625385379895617796">Vaše hodiny jdou napřed</translation>
<translation id="2639739919103226564">Stav:</translation>
+<translation id="2653659639078652383">Odeslat</translation>
<translation id="2704283930420550640">Hodnota neodpovídá formátu.</translation>
<translation id="2721148159707890343">Požadavek byl úspěšný</translation>
+<translation id="2728127805433021124">Certifikát serveru je podepsán slabým algoritmem.</translation>
<translation id="2774256287122201187">Můžete pokračovat. Pokud na stránku budete pokračovat, toto upozornění se pět minut nebude zobrazovat.</translation>
<translation id="277499241957683684">Chybějící záznam zařízení</translation>
<translation id="2835170189407361413">Vymazat formulář</translation>
-<translation id="2855922900409897335">Ověření karty <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Ověření karty <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Tento server nemohl prokázat, že patří do domény <ph name="DOMAIN" />. Platnost jeho bezpečnostního certifikátu vypršela. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaše připojení zachytává útočník. Hodiny ve vašem počítači jsou aktuálně nastaveny na <ph name="CURRENT_TIME" />. Je to správně? Pokud ne, měli byste čas v počítači opravit a poté tuto stránku načíst znovu.</translation>
+<translation id="2922350208395188000">Certifikát serveru nelze zkontrolovat.</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="2958431318199492670">Konfigurace sítě nesplňuje standard ONC. Může se stát, že některé části konfigurace nebudou importovány.</translation>
<translation id="2972581237482394796">&amp;Opakovat</translation>
-<translation id="3010559122411665027">Položka seznamu „<ph name="ENTRY_INDEX"/>“: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Položka seznamu „<ph name="ENTRY_INDEX" />“: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Chybný typ zásady</translation>
<translation id="3105172416063519923">ID díla:</translation>
<translation id="3145945101586104090">Dekódování odpovědi se nezdařilo</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ostrov</translation>
<translation id="3219579145727097045">Zadejte datum vypršení platnosti a čtyřmístný kód CVC z přední strany karty</translation>
-<translation id="3228969707346345236">Překlad se nezdařil. Stránka je již v jazyce <ph name="LANGUAGE"/>.</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="3228969707346345236">Překlad se nezdařil. Stránka je již v jazyce <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Vrátit změnu uspořádání zpět</translation>
+<translation id="3286538390144397061">Restartovat</translation>
<translation id="333371639341676808">Bránit této stránce ve vytváření dalších dialogových oken.</translation>
-<translation id="3369366829301677151">Aktualizujte a ověřte svou platební kartu <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">nastavení</translation>
+<translation id="3369192424181595722">Chyba hodin</translation>
+<translation id="3369366829301677151">Aktualizujte a ověřte svou platební kartu <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Vyřazeno</translation>
<translation id="3377188786107721145">Chyba analýzy zásady</translation>
<translation id="3380365263193509176">Neznámá chyba</translation>
<translation id="3380864720620200369">Číslo klienta:</translation>
<translation id="3427342743765426898">&amp;Opakovat úpravy</translation>
+<translation id="3435896845095436175">Aktivovat</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Interval načtení:</translation>
+<translation id="3462200631372590220">Skrýt rozšířené</translation>
+<translation id="3528171143076753409">Certifikát serveru není důvěryhodný.</translation>
<translation id="3542684924769048008">Použít heslo pro:</translation>
<translation id="3583757800736429874">&amp;Opakovat přesunutí</translation>
<translation id="3623476034248543066">Zobrazit hodnotu</translation>
+<translation id="3648607100222897006">Tyto experimentální funkce se mohou kdykoli změnit, zhroutit nebo zmizet. Nemůžeme vůbec zaručit, co se po zapnutí těchto experimentů stane. Prohlížeč může například samovolně vybouchnout. Ale bez legrace: Prohlížeč může smazat veškeré vaše údaje nebo neočekávanými způsoby narušit vaše zabezpečení či soukromí. Experimenty, které zapnete, budou k dispozici všem uživatelům prohlížeče. Buďte prosím obezřetní.</translation>
<translation id="3650584904733503804">Ověření proběhlo úspěšně</translation>
<translation id="370665806235115550">Načítání...</translation>
<translation id="3712624925041724820">Byly vyčerpány licence</translation>
<translation id="3739623965217189342">Zkopírovaný odkaz</translation>
<translation id="375403751935624634">Z důvodu chyby serveru se překlad nezdařil.</translation>
<translation id="385051799172605136">Zpět</translation>
+<translation id="3858027520442213535">Aktualizovat datum a čas</translation>
<translation id="3884278016824448484">Konfliktní identifikátor zařízení</translation>
<translation id="3885155851504623709">Okrsek</translation>
<translation id="3934680773876859118">Načítání dokumentu PDF se nezdařilo.</translation>
<translation id="3963721102035795474">Režim čtečky</translation>
<translation id="4030383055268325496">&amp;Vrátit přidání zpět</translation>
-<translation id="4058922952496707368">Klíč <ph name="SUBKEY"/>: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">UPOZORNĚNÍ</translation>
+<translation id="4058922952496707368">Klíč <ph name="SUBKEY" />: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Proxy je nastaveno na používání adresy URL skriptu PAC, nikoliv pevně daných serverů proxy.</translation>
<translation id="409504436206021213">Nenačítat</translation>
<translation id="4103249731201008433">Sériové číslo zařízení je neplatné</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Chybný podpis</translation>
<translation id="4269787794583293679">(Žádné uživatelské jméno)</translation>
<translation id="4300246636397505754">Návrhy rodičů</translation>
-<translation id="4372948949327679948">Očekávána hodnota <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Článek nebyl nalezen</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="4394049700291259645">Deaktivovat</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="443673843213245140">Využití proxy serveru je zakázáno, je však určena explicitní konfigurace proxy serveru.</translation>
-<translation id="4506176782989081258">Chyba ověřování: <ph name="VALIDATION_ERROR"/>.</translation>
+<translation id="4506176782989081258">Chyba ověřování: <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4587425331216688090">Odstranit adresu z Chromu?</translation>
<translation id="4594403342090139922">&amp;Vrátit smazání zpět</translation>
<translation id="4607653538520819196">Tuto stránku prostřednictvím proxy serverů Spořiče dat nelze zprostředkovat.</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="4726672564094551039">Znovu načíst zásady</translation>
+<translation id="4728558894243024398">Platforma</translation>
+<translation id="4771973620359291008">Došlo k neznámé chybě.</translation>
<translation id="4800132727771399293">Zkontrolujte datum vypršení platnosti a kód CVC a zkuste to znovu.</translation>
<translation id="4813512666221746211">Chyba sítě</translation>
+<translation id="4816492930507672669">Přizpůsobit na stránku</translation>
<translation id="4850886885716139402">Zobrazit</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="4923417429809017348">Tato stránka byla přeložena z neznámého jazyka do jazyka <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Musí být uvedeno</translation>
<translation id="4968547170521245791">Nelze zprostředkovat</translation>
-<translation id="498957508165411911">Přeložit z jazyka <ph name="ORIGINAL_LANGUAGE"/> do jazyka <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Přeložit z jazyka <ph name="ORIGINAL_LANGUAGE" /> do jazyka <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Záložní úložiště je ve špatném stavu</translation>
<translation id="5031870354684148875">O Překladači Google</translation>
+<translation id="5045550434625856497">Nesprávné heslo</translation>
+<translation id="5087286274860437796">Certifikát serveru v tuto chvíli není platný.</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="5145883236150621069">Odpověď zásady obsahuje kód chyby</translation>
<translation id="5172758083709347301">Počítač</translation>
-<translation id="5179510805599951267">Nejedná se o jazyk <ph name="ORIGINAL_LANGUAGE"/>? Nahlaste tuto chybu.</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="5199729219167945352">Experimenty</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">Potvrdit navigaci</translation>
<translation id="5299298092464848405">Při analýze zásady došlo k chybě</translation>
+<translation id="5316812925700871227">Otočit proti směru hodinových ručiček</translation>
<translation id="5317780077021120954">Uložit</translation>
<translation id="536296301121032821">Ukládání nastavení zásady se nezdařilo</translation>
-<translation id="5439770059721715174">Chyba validace schématu v místě <ph name="ERROR_PATH"/>: <ph name="ERROR"/></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="5439770059721715174">Chyba validace schématu v místě <ph name="ERROR_PATH" />: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Chybné časové razítko zásady</translation>
<translation id="5470861586879999274">&amp;Opakovat úpravy</translation>
<translation id="5509780412636533143">Spravované záložky</translation>
<translation id="5523118979700054094">Název zásady</translation>
<translation id="552553974213252141">Byl text extrahován správně?</translation>
<translation id="5540224163453853">Požadovaný článek nebyl nalezen.</translation>
+<translation id="5556459405103347317">Načíst znovu</translation>
<translation id="5565735124758917034">Aktivní</translation>
<translation id="560412284261940334">Správa není podporována</translation>
<translation id="5629630648637658800">Načítání nastavení zásady se nezdařilo</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Aktuální uživatel</translation>
<translation id="5813119285467412249">&amp;Opakovat přidání</translation>
<translation id="5872918882028971132">Návrhy rodičů</translation>
-<translation id="587701087903783706">Zavřít zobrazení optimalizované pro mobily</translation>
<translation id="59107663811261420">Tento typ karty ve službě Google Payments u tohoto obchodníka není podporován. Vyberte prosím jinou kartu.</translation>
+<translation id="5975083100439434680">Oddálit</translation>
<translation id="5989320800837274978">Nejsou určeny pevně dané servery proxy ani adresa URL skriptu PAC.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Zavřít</translation>
+<translation id="6060685159320643512">Pozor, tyto experimenty mohou skončit všelijak.</translation>
+<translation id="6151417162996330722">Certifikát serveru má příliš dlouhé období platnosti.</translation>
<translation id="6154808779448689242">Vrácený token zásad neodpovídá aktuálnímu tokenu</translation>
<translation id="6165508094623778733">Další informace</translation>
<translation id="6259156558325130047">&amp;Opakovat změnu uspořádání</translation>
-<translation id="6263376278284652872">Záložky webu <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Záložky webu <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">PSČ</translation>
<translation id="6337534724793800597">Filtrovat zásady podle názvu</translation>
+<translation id="6387478394221739770">Zajímají vás nové funkce Chromu? Vyzkoušejte kanál beta na adrese chrome.com/beta.</translation>
+<translation id="6426993025560594914">Na vaší platformě jsou k dispozici všechny experimenty.</translation>
<translation id="6445051938772793705">Země</translation>
<translation id="6458467102616083041">Ignorováno, protože výchozí vyhledávání je zakázáno zásadou.</translation>
<translation id="647261751007945333">Zásady zařízení</translation>
<translation id="6512448926095770873">Opustit tuto stránku</translation>
<translation id="6529602333819889595">&amp;Opakovat smazání</translation>
<translation id="6550675742724504774">Možnosti</translation>
-<translation id="6597614308054261376">Pokoušíte se přejít na stránku <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Tuto stránku v současné době prostřednictvím proxy serverů Spořiče dat nelze zprostředkovat.</translation>
-<translation id="6628463337424475685">Vyhledávání <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Pokoušíte se přejít na stránku <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Tuto stránku v současné době prostřednictvím proxy serverů Spořiče dat nelze zprostředkovat.</translation>
+<translation id="6628463337424475685">Vyhledávání <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Tato zásada se již nepoužívá.</translation>
<translation id="6646897916597483132">Zadejte čtyřmístný kód CVC z přední strany karty</translation>
+<translation id="674375294223700098">Neznámá chyba certifikátu serveru.</translation>
<translation id="6753269504797312559">Hodnota zásady</translation>
<translation id="6831043979455480757">Přeložit</translation>
<translation id="6839929833149231406">Region</translation>
<translation id="6874604403660855544">&amp;Opakovat přidání</translation>
<translation id="6891596781022320156">Úroveň zásady není podporována.</translation>
<translation id="6915804003454593391">Uživatel:</translation>
+<translation id="6957887021205513506">Zdá se, že certifikát serveru je podvrh.</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6965978654500191972">Zařízení</translation>
<translation id="6970216967273061347">Obvod</translation>
<translation id="6973656660372572881">Určeny jsou pevně dané servery proxy i adresa URL skriptu PAC.</translation>
<translation id="6980028882292583085">JavaScript – výstraha</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Pokusili jste se připojit k doméně <ph name="DOMAIN" />, ale server předložil certifikát, který má příliš dlouhé období platnosti a je proto nedůvěryhodný.</translation>
<translation id="7087282848513945231">Obvod</translation>
-<translation id="7108649287766967076">Překlad do jazyka <ph name="TARGET_LANGUAGE"/> se nezdařil.</translation>
+<translation id="7108649287766967076">Překlad do jazyka <ph name="TARGET_LANGUAGE" /> se nezdařil.</translation>
<translation id="7139724024395191329">Emirát</translation>
+<translation id="7179921470347911571">Spustit znovu</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="7186367841673660872">Tato stránka byla přeložena z jazyka<ph name="ORIGINAL_LANGUAGE" />do jazyka<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Vyhledat <ph name="SEARCH_TERMS"/> na <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Vyhledat <ph name="SEARCH_TERMS" /> na <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">Soukromé připojení k doméně <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nelze navázat, protože máte v počítači nastaveno chybné datum a čas (<ph name="DATE_AND_TIME" />).</translation>
<translation id="7275334191706090484">Spravované záložky</translation>
<translation id="7298195798382681320">Doporučeno</translation>
<translation id="7334320624316649418">&amp;Opakovat změnu uspořádání</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Povinná</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="7568593326407688803">Tato stránka je v jazyce<ph name="ORIGINAL_LANGUAGE"/>Chcete ji přeložit?</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="7568593326407688803">Tato stránka je v jazyce<ph name="ORIGINAL_LANGUAGE" />Chcete ji přeložit?</translation>
<translation id="7569952961197462199">Odstranit platební kartu z Chromu?</translation>
-<translation id="7600965453749440009">Jazyk <ph name="LANGUAGE"/> nikdy nepřekládat</translation>
-<translation id="7610193165460212391">Hodnota <ph name="VALUE"/> je mimo rozsah.</translation>
+<translation id="7592362899630581445">Certifikát serveru porušuje omezení názvů domén.</translation>
+<translation id="7600965453749440009">Jazyk <ph name="LANGUAGE" /> nikdy nepřekládat</translation>
+<translation id="7610193165460212391">Hodnota <ph name="VALUE" /> je mimo rozsah.</translation>
+<translation id="7674629440242451245">Zajímají vás nové funkce Chromu? Vyzkoušejte kanál pro vývojáře na adrese chrome.com/dev.</translation>
<translation id="7752995774971033316">Nespravováno</translation>
+<translation id="7761701407923456692">Certifikát serveru neodpovídá adrese URL.</translation>
<translation id="777702478322588152">Prefektura</translation>
<translation id="7791543448312431591">Přidat</translation>
<translation id="7805768142964895445">Stav</translation>
<translation id="7813600968533626083">Odstranit návrh položky formuláře z Chromu?</translation>
<translation id="7887683347370398519">Zkontrolujte kód CVC a zkuste to znovu</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Certifikát serveru ještě není platný.</translation>
<translation id="7956713633345437162">Mobilní záložky</translation>
<translation id="7961015016161918242">Nikdy</translation>
<translation id="7977590112176369853">&lt;zadat dotaz&gt;</translation>
-<translation id="7983301409776629893">Vždy překládat z jazyka <ph name="ORIGINAL_LANGUAGE"/> do jazyka <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Vždy překládat z jazyka <ph name="ORIGINAL_LANGUAGE" /> do jazyka <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Záložky v PC</translation>
<translation id="7995512525968007366">Není zadáno</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="8003882219468422867">Přepsání podnikového nastavení</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="8088680233425245692">Zobrazení článku se nezdařilo.</translation>
<translation id="8091372947890762290">Čeká se na aktivaci na serveru</translation>
<translation id="8194797478851900357">&amp;Vrátit přesunutí zpět</translation>
-<translation id="8201077131113104583">Neplatná adresa URL aktualizace rozšíření s ID <ph name="EXTENSION_ID"/>.</translation>
+<translation id="8201077131113104583">Neplatná adresa URL aktualizace rozšíření s ID <ph name="EXTENSION_ID" />.</translation>
<translation id="8208216423136871611">Neukládat</translation>
<translation id="8218327578424803826">Přiřazené místo:</translation>
<translation id="8249320324621329438">Naposledy načteno:</translation>
+<translation id="8294431847097064396">Zdroj</translation>
<translation id="8308427013383895095">Překlad se nezdařil kvůli problému s připojením k síti.</translation>
<translation id="8311778656528046050">Opravdu chcete tuto stránku znovu načíst?</translation>
<translation id="8349305172487531364">Lišta záložek</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Platí pro</translation>
<translation id="8530504477309582336">Služba Google Payments tento typ karty nepodporuje. Vyberte prosím jinou kartu.</translation>
<translation id="8553075262323480129">Překlad se nezdařil. Nepodařilo se rozpoznat jazyk stránky.</translation>
-<translation id="8571890674111243710">Překlad stránky do jazyka: <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Soukromé připojení k doméně <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nelze navázat, protože máte v zařízení nastaveno chybné datum a čas (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="8571890674111243710">Překlad stránky do jazyka: <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Obnovit u všech experimentů výchozí nastavení</translation>
<translation id="8713130696108419660">Nesprávný počáteční podpis</translation>
<translation id="8725066075913043281">Zkusit znovu</translation>
+<translation id="8738058698779197622">Aby bylo možné navázat zabezpečené spojení, hodiny musejí být nastaveny správně. Důvodem je, že certifikáty, pomocí kterých se weby identifikují, platí pouze pro pevně daná období. Jelikož hodiny v zařízení nejsou nastaveny správně, prohlížeč Chromium tyto certifikáty nemůže ověřit.</translation>
<translation id="8790007591277257123">&amp;Opakovat smazání</translation>
<translation id="8804164990146287819">Zásady ochrany soukromí</translation>
+<translation id="8820817407110198400">Záložky</translation>
<translation id="8824019021993735287">Chrome vaši kartu aktuálně nemohli ověřit. Zkuste to znovu později.</translation>
<translation id="8834246243508017242">Povolit automatické vyplňování pomocí Kontaktů…</translation>
<translation id="883848425547221593">Jiné záložky</translation>
+<translation id="884923133447025588">Nebyl nalezen žádný mechanismus zamítnutí.</translation>
<translation id="8866481888320382733">Při analýze nastavení zásady došlo k chybě</translation>
<translation id="8876793034577346603">Analýza konfigurace sítě se nezdařila.</translation>
<translation id="8891727572606052622">Neplatný režim proxy serveru.</translation>
-<translation id="8940229512486821554">Spustit příkaz rozšíření <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Je nám líto, tento experiment není na vaší platformě dostupný.</translation>
+<translation id="8903921497873541725">Přiblížit</translation>
+<translation id="8932102934695377596">Vaše hodiny se zpožďují</translation>
+<translation id="8940229512486821554">Spustit příkaz rozšíření <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Platnost certifikátu serveru vypršela.</translation>
<translation id="8988760548304185580">Zadejte datum vypršení platnosti a třímístný kód CVC ze zadní strany karty</translation>
-<translation id="9020542370529661692">Stránka byla přeložena do jazyka <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Příznaky, které platí v celém systému, může nastavit pouze vlastník: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Stránka byla přeložena do jazyka <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Pokusili jste se přejít do domény <ph name="DOMAIN" />, ale server předložil certifikát, jehož platnost vypršela.</translation>
<translation id="9125941078353557812">Zadejte třípísmenný kód CVC uvedený na zadní straně karty.</translation>
<translation id="9137013805542155359">Zobrazit originál</translation>
<translation id="9148507642005240123">&amp;Vrátit úpravy zpět</translation>
<translation id="9154176715500758432">Zůstat na této stránce</translation>
<translation id="9170848237812810038">Z&amp;pět</translation>
+<translation id="917450738466192189">Certifikát serveru je neplatný.</translation>
+<translation id="9187827965378254003">Bohužel to vypadá, že nejsou k dispozici žádné experimenty.</translation>
<translation id="9207861905230894330">Přidání článku se nezdařilo.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">VYMAZAT FORMULÁŘ</translation>
+<translation id="988159990683914416">Vývojářské sestavení</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_da.xtb b/chromium/components/strings/components_strings_da.xtb
index d65254c431b..5ac8c9f3d04 100644
--- a/chromium/components/strings/components_strings_da.xtb
+++ b/chromium/components/strings/components_strings_da.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="da">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="da">
+<translation id="1032854598605920125">Rotér med uret</translation>
<translation id="1055184225775184556">&amp;Fortryd tilføjelse</translation>
<translation id="106701514854093668">Bogmærker på pc</translation>
-<translation id="1103523840287552314">Oversæt altid <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Tilpas til bredden</translation>
+<translation id="1103523840287552314">Oversæt altid <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Fortryd omarrangering</translation>
<translation id="111844081046043029">Er du sikker på, at du vil forlade denne side?</translation>
<translation id="112840717907525620">Cache for politik er OK</translation>
<translation id="1132774398110320017">Indstillinger for Autofyld i Chrome...</translation>
-<translation id="1152921474424827756">Få adgang til en <ph name="BEGIN_LINK"/>cachelagret kopi<ph name="END_LINK"/> af <ph name="URL"/></translation>
+<translation id="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="1152921474424827756">Få adgang til en <ph name="BEGIN_LINK" />cachelagret kopi<ph name="END_LINK" /> af <ph name="URL" /></translation>
+<translation id="121201262018556460">Du har forsøgt at få fat i <ph name="DOMAIN" />, men serveren har præsenteret et certifikat med en svag nøgle. En hacker kan have knækket den private nøgle, og serveren er muligvis ikke den forventede server (du kommunikerer muligvis med en hacker).</translation>
<translation id="1227224963052638717">Ukendt politik.</translation>
<translation id="1227633850867390598">Skjul værdi</translation>
<translation id="1228893227497259893">Forkert enheds-id</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Registreringsdomæne:</translation>
<translation id="1344588688991793829">Indstillinger for AutoFyld i Chromium...</translation>
<translation id="1426410128494586442">Ja</translation>
+<translation id="1430915738399379752">Udskriv</translation>
<translation id="1455235771979731432">Dit kort kunne ikke godkendes. Kontrollér at du har forbindelse til internettet, og prøv igen.</translation>
<translation id="1491151370853475546">Genindlæs denne side</translation>
<translation id="1549470594296187301">JavaScript skal være aktiveret, før du kan bruge denne funktion.</translation>
-<translation id="1639239467298939599">Indlæser...</translation>
<translation id="1640180200866533862">Brugerpolitikker</translation>
<translation id="1644184664548287040">Netværkskonfigurationen er ugyldig og kunne ikke importeres.</translation>
-<translation id="1693754753824026215">Siden på <ph name="SITE"/> siger:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da dens sikkerhedscertifikat udløb i går. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. Computerens ur er angivet til <ph name="CURRENT_DATE" />. Er det korrekt? Hvis ikke, skal du rette systemets ur og derefter opdatere denne side.}one{Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da dens sikkerhedscertifikat udløb for # dag siden. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. Computerens ur er angivet til <ph name="CURRENT_DATE" />. Er det korrekt? Hvis ikke, skal du rette systemets ur og derefter opdatere denne side.}other{Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da dens sikkerhedscertifikat udløb for # dage siden. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. Computerens ur er angivet til <ph name="CURRENT_DATE" />. Er det korrekt? Hvis ikke, skal du rette systemets ur og derefter opdatere denne side.}}</translation>
+<translation id="168841957122794586">Servercertifikatet indeholder en svag kryptografisk nøgle.</translation>
+<translation id="1693754753824026215">Siden på <ph name="SITE" /> siger:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da operativsystemet på din enhed ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
<translation id="1821930232296380041">Ugyldig anmodning eller anmodningsparametre</translation>
-<translation id="1853748787962613237">Artiklen kunne ikke vises.</translation>
<translation id="1871208020102129563">Proxy er indstillet til at bruge faste proxyservere, ikke webadresser til .pac-scripts.</translation>
-<translation id="1875753206475436906">heuristisk type: <ph name="HEURISTIC_TYPE"/>
- servertype: <ph name="SERVER_TYPE"/>
- feltsignatur: <ph name="FIELD_SIGNATURE"/>
- formsignatur: <ph name="FORM_SIGNATURE"/>
- test-id: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Gå til <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Bogmærker fra <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Gå til <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Bogmærker fra <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Serialiseringsfejl</translation>
+<translation id="1974060860693918893">Avanceret</translation>
<translation id="2025186561304664664">Proxyen konfigureres automatisk.</translation>
<translation id="2025623846716345241">Bekræft genindlæsning</translation>
-<translation id="2030481566774242610">Mente du <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Mente du <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Postnummer</translation>
<translation id="20817612488360358">Indstillingerne for systemproxy er angivet at blive brugt, men en eksplicit proxykonfiguration er også angivet.</translation>
<translation id="2094505752054353250">Uoverensstemmelse mellem domæner</translation>
<translation id="2096368010154057602">Departement</translation>
<translation id="2113977810652731515">Kort</translation>
-<translation id="2114841414352855701">Ignoreret, da den blev tilsidesat af <ph name="POLICY_NAME"/> .</translation>
+<translation id="2114841414352855701">Ignoreret, da den blev tilsidesat af <ph name="POLICY_NAME" /> .</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Bogmærker på mobil</translation>
+<translation id="2171101176734966184">Du forsøgte at få fat på <ph name="DOMAIN" />, men serveren har præsenteret et certifikat, der er signeret med en svag signaturalgoritme. Det betyder, at sikkerhedsoplysningerne fra serveren kan være forfalskede, og at serveren muligvis ikke er den server, som du har forventet (du kommunikerer muligvis med en hacker).</translation>
<translation id="2181821976797666341">Politikker</translation>
<translation id="2212735316055980242">Politikken blev ikke fundet</translation>
<translation id="2213606439339815911">Indlæg hentes...</translation>
<translation id="225207911366869382">Denne værdi er forældet for denne politik.</translation>
<translation id="2262243747453050782">HTTP-fejl</translation>
-<translation id="2270192940992995399">Artiklen kunne ikke findes.</translation>
-<translation id="2328300916057834155">Ugyldigt bogmærke ved indeks <ph name="ENTRY_INDEX"/> er ignoreret</translation>
+<translation id="2282872951544483773">Utilgængelige eksperimenter</translation>
+<translation id="229702904922032456">Et rodcertifikat eller et midlertidigt certifikat er udløbet.</translation>
+<translation id="2328300916057834155">Ugyldigt bogmærke ved indeks <ph name="ENTRY_INDEX" /> er ignoreret</translation>
<translation id="2354001756790975382">Andre bogmærker</translation>
<translation id="2359808026110333948">Fortsæt</translation>
<translation id="2367567093518048410">Niveau</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="2396249848217231973">&amp;Fortryd sletning</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="2455981314101692989">Denne webside har deaktiveret automatisk udfyldning af denne formular.</translation>
<translation id="2479410451996844060">Ugyldig søgewebadresse.</translation>
+<translation id="2491120439723279231">Serverens certifikat indeholder fejl.</translation>
<translation id="2495083838625180221">Værktøj til parsing af JSON-filer</translation>
<translation id="2498091847651709837">Scan et nyt kort</translation>
<translation id="2556876185419854533">&amp;Fortryd redigering</translation>
-<translation id="2581221116934462656">Skal <ph name="PRODUCT_NAME"/> tilbyde at oversætte sider på <ph name="LANGUAGE_NAME"/> fra dette website næste gang?</translation>
+<translation id="2581221116934462656">Skal <ph name="PRODUCT_NAME" /> tilbyde at oversætte sider på <ph name="LANGUAGE_NAME" /> fra dette website næste gang?</translation>
<translation id="2587841377698384444">Id for Directory API:</translation>
<translation id="2597378329261239068">Dette dokument er adgangskodebeskyttet. Indtast en adgangskode.</translation>
+<translation id="2625385379895617796">Dit ur er foran</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2653659639078652383">Indsend</translation>
<translation id="2704283930420550640">Værdien stemmer ikke overens med formatet.</translation>
<translation id="2721148159707890343">Anmodning lykkedes</translation>
+<translation id="2728127805433021124">Serverens certifikat er signeret ved hjælp af en svag signaturalgoritme.</translation>
<translation id="2774256287122201187">Du kan nu fortsætte. Denne advarsel vises ikke igen i de næste fem minutter, hvis du fortsætter til siden.</translation>
<translation id="277499241957683684">Manglende enhedsregistrering</translation>
<translation id="2835170189407361413">Ryd formular</translation>
-<translation id="2855922900409897335">Bekræft dit <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Bekræft dit <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da sikkerhedscertifikatet er udløbet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. Uret på din computer er indstillet til <ph name="CURRENT_TIME" />. Er det korrekt? Hvis ikke, skal du indstille uret og opdatere siden.</translation>
+<translation id="2922350208395188000">Serverens certifikat kan ikke kontrolleres.</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="2958431318199492670">Netværkskonfigurationen overholder ikke ONC-standarden. Dele af konfiguration kan muligvis ikke importeres.</translation>
<translation id="2972581237482394796">&amp;Annuller fortryd</translation>
-<translation id="3010559122411665027">Angiv posten &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Angiv posten "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Forkert politiktype</translation>
<translation id="3105172416063519923">Aktiv-id:</translation>
<translation id="3145945101586104090">Svaret kunne ikke afkodes</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ø</translation>
<translation id="3219579145727097045">Indtast udløbsdatoen og den firecifrede kontrolkode, som ses på forsiden af dit kort</translation>
-<translation id="3228969707346345236">Oversættelsen mislykkedes, fordi siden allerede er på <ph name="LANGUAGE"/>.</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="3228969707346345236">Oversættelsen mislykkedes, fordi siden allerede er på <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Fortryd omarrangering</translation>
+<translation id="3286538390144397061">Genstart nu</translation>
<translation id="333371639341676808">Undgå, at denne side laver nye dialogbokse.</translation>
-<translation id="3369366829301677151">Opdater og bekræft dit <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">indstillinger</translation>
+<translation id="3369192424181595722">Urfejl</translation>
+<translation id="3369366829301677151">Opdater og bekræft dit <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Fjernet</translation>
<translation id="3377188786107721145">Det opstod en fejl ved parsing af politik</translation>
<translation id="3380365263193509176">Ukendt fejl</translation>
<translation id="3380864720620200369">Klient-id:</translation>
<translation id="3427342743765426898">&amp;Annuller fortryd redigering</translation>
+<translation id="3435896845095436175">Aktiver</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Hent interval:</translation>
+<translation id="3462200631372590220">Skjul avanceret</translation>
+<translation id="3528171143076753409">Serverens certifikat er ikke troværdigt.</translation>
<translation id="3542684924769048008">Brug adgangskode til:</translation>
<translation id="3583757800736429874">&amp;Annuller fortryd flytning</translation>
<translation id="3623476034248543066">Vis værdi</translation>
+<translation id="3648607100222897006">Disse eksperimentelle funktioner kan ændre sig, gå i stykker eller forsvinde når som helst. Vi giver absolut ingen garantier for, hvad der kan ske, hvis du aktiverer en af ​​disse eksperimentelle funktioner, og din browser kan måske endda finde på spontant at selvantænde. Spøg til side. Din browser kan muligvis slette alle dine data, eller din sikkerhed eller dine personlige oplysninger kan komme i fare på uventet vis. Enhver eksperimentel funktion, du aktiverer, aktiveres for alle brugere af denne browser. Vær forsigtig, hvis du fortsætter.</translation>
<translation id="3650584904733503804">Valideringen er fuldført</translation>
<translation id="370665806235115550">Indlæser...</translation>
<translation id="3712624925041724820">Licenserne er opbrugt</translation>
<translation id="3739623965217189342">Link, du har kopieret</translation>
<translation id="375403751935624634">Oversættelsen mislykkedes på grund af en serverfejl.</translation>
<translation id="385051799172605136">Tilbage</translation>
+<translation id="3858027520442213535">Opdater dato og tid</translation>
<translation id="3884278016824448484">Modstridende enheds-id</translation>
<translation id="3885155851504623709">Sogn</translation>
<translation id="3934680773876859118">PDF-dokumentet kunne ikke indlæses</translation>
<translation id="3963721102035795474">Læser-tilstand</translation>
<translation id="4030383055268325496">&amp;Fortryd tilføjelse</translation>
-<translation id="4058922952496707368">Nøgle &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ADVARSEL</translation>
+<translation id="4058922952496707368">Nøgle "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Proxykonfiguration er angivet til at anvende en webadresse for .pac-script, ikke faste proxyservere.</translation>
<translation id="409504436206021213">Annuller genindlæsning</translation>
<translation id="4103249731201008433">Enhedens serienummer er ugyldigt</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Forkert signatur</translation>
<translation id="4269787794583293679">(Intet brugernavn)</translation>
<translation id="4300246636397505754">Forslag fra forældre</translation>
-<translation id="4372948949327679948">Forventet <ph name="VALUE_TYPE"/>-værdi.</translation>
+<translation id="4325863107915753736">Artiklen blev ikke fundet.</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="4394049700291259645">Deaktiver</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="443673843213245140">Brug af en proxy er deaktiveret, men en eksplicit proxykonfiguration er angivet.</translation>
-<translation id="4506176782989081258">Valideringsfejl: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Valideringsfejl: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Vil du fjerne adressen fra Chrome?</translation>
<translation id="4594403342090139922">&amp;Fortryd sletning</translation>
<translation id="4607653538520819196">Denne side kan ikke oprettes via proxy med datasparefunktion.</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="4726672564094551039">Opdater politikker</translation>
+<translation id="4728558894243024398">Platform</translation>
+<translation id="4771973620359291008">Der er opstået en ukendt fejl.</translation>
<translation id="4800132727771399293">Kontrollér, om din kontrolkode og udløbsdato er korrekte, og prøv igen.</translation>
<translation id="4813512666221746211">Netværksfejl</translation>
+<translation id="4816492930507672669">Tilpas til siden</translation>
<translation id="4850886885716139402">Vis</translation>
-<translation id="4923417429809017348">Denne side er oversat fra et ukendt sprog til <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Denne side er oversat fra et ukendt sprog til <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Skal angives.</translation>
<translation id="4968547170521245791">Kan ikke oprettes via proxy</translation>
-<translation id="498957508165411911">Vil du oversætte fra <ph name="ORIGINAL_LANGUAGE"/> til <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Vil du oversætte fra <ph name="ORIGINAL_LANGUAGE" /> til <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Sikkerhedskopien er fejlbehæftet</translation>
<translation id="5031870354684148875">Om Google Oversæt</translation>
+<translation id="5045550434625856497">Ugyldig adgangskode</translation>
+<translation id="5087286274860437796">Serverens certifikatet er ikke gyldigt i øjeblikket.</translation>
<translation id="5089810972385038852">Delstat</translation>
+<translation id="5094747076828555589">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da Chromium ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
<translation id="5095208057601539847">Provins</translation>
<translation id="5145883236150621069">Fejlkode til stede i politiksvar</translation>
<translation id="5172758083709347301">Maskine</translation>
-<translation id="5179510805599951267">Ikke på <ph name="ORIGINAL_LANGUAGE"/>? Rapporter denne fejl</translation>
+<translation id="5179510805599951267">Ikke på <ph name="ORIGINAL_LANGUAGE" />? Rapporter denne fejl</translation>
<translation id="5190835502935405962">Bogmærkelinje</translation>
+<translation id="5199729219167945352">Eksperimenter</translation>
+<translation id="5251803541071282808">Skyen</translation>
<translation id="5295309862264981122">Bekræft navigation</translation>
<translation id="5299298092464848405">Der opstod en fejl ved parsing af politik</translation>
+<translation id="5316812925700871227">Rotér mod uret</translation>
<translation id="5317780077021120954">Gem</translation>
<translation id="536296301121032821">Der kunne ikke gemmes indstillinger for politik</translation>
-<translation id="5439770059721715174">Skemavalideringsfejl på &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Skemavalideringsfejl på "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Forkert tidsstempel for politik</translation>
<translation id="5470861586879999274">&amp;Annuller fortryd redigering</translation>
<translation id="5509780412636533143">Administrerede bogmærker</translation>
<translation id="5523118979700054094">Navn på politik</translation>
<translation id="552553974213252141">Blev teksten trukket korrekt ud?</translation>
<translation id="5540224163453853">Den anmodede artikel kunne ikke findes.</translation>
+<translation id="5556459405103347317">Genindlæs</translation>
<translation id="5565735124758917034">Aktiv</translation>
<translation id="560412284261940334">Administration er ikke understøttet</translation>
<translation id="5629630648637658800">Der kunne ikke indlæses indstillinger for politik</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Aktuel bruger</translation>
<translation id="5813119285467412249">&amp;Annuller fortryd tilføjelse</translation>
<translation id="5872918882028971132">Forslag fra forældre</translation>
-<translation id="587701087903783706">Luk den mobilvenlige visning</translation>
<translation id="59107663811261420">Denne korttype understøttes ikke af Google Payments for denne sælger. Vælg et andet kort.</translation>
+<translation id="5975083100439434680">Zoom ud</translation>
<translation id="5989320800837274978">Der er hverken angivet faste proxyservere eller en .pac-scriptwebadresse.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Luk</translation>
+<translation id="6060685159320643512">Vær forsigtig. Disse eksperimenter kan være farlige</translation>
+<translation id="6151417162996330722">Servercertifikatet har en gyldighedsperiode, der er for lang.</translation>
<translation id="6154808779448689242">Det returnerede token for politikken stemmer ikke overens med det nuværende token</translation>
<translation id="6165508094623778733">Flere oplysninger</translation>
<translation id="6259156558325130047">&amp;Annuller fortryd omarrangering</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/>-bogmærker</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" />-bogmærker</translation>
<translation id="6282194474023008486">Postnummer</translation>
<translation id="6337534724793800597">Filtrer politikker efter navn</translation>
+<translation id="6387478394221739770">Er du interesseret i smarte nye Chrome-funktioner? Prøv vores betakanal på chrome.com/beta.</translation>
+<translation id="6426993025560594914">Alle eksperimenter er tilgængelige på din platform.</translation>
<translation id="6445051938772793705">Land</translation>
<translation id="6458467102616083041">Ignoreret, fordi standardsøgning er deaktiveret af politikken.</translation>
<translation id="647261751007945333">Enhedspolitikker</translation>
<translation id="6512448926095770873">Forlad denne side</translation>
<translation id="6529602333819889595">&amp;Annuller fortryd slet</translation>
<translation id="6550675742724504774">Valgmuligheder</translation>
-<translation id="6597614308054261376">Du forsøger at gå til <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Denne side kan ikke oprettes via proxy med datasparefunktion på nuværende tidspunkt.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Søg</translation>
+<translation id="6597614308054261376">Du forsøger at gå til <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Denne side kan ikke oprettes via proxy med datasparefunktion på nuværende tidspunkt.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Søg</translation>
<translation id="6644283850729428850">Denne politik er forældet.</translation>
<translation id="6646897916597483132">Indtast den firecifrede kontrolkode, som ses på forsiden af dit kort</translation>
+<translation id="674375294223700098">Ukendt fejl i servercertifikatet.</translation>
<translation id="6753269504797312559">Politikkens værdi</translation>
<translation id="6831043979455480757">Oversæt</translation>
<translation id="6839929833149231406">Område</translation>
<translation id="6874604403660855544">&amp;Annuller fortryd tilføjelse</translation>
<translation id="6891596781022320156">Politikniveauet understøttes ikke.</translation>
<translation id="6915804003454593391">Bruger:</translation>
+<translation id="6957887021205513506">Serverens certifikat ser ud til at være en forfalskning.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">JavaScript-advarsel</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Du forsøgte at gå til <ph name="DOMAIN" />, men serveren præsenterede et certifikat, hvis gyldighedsperiode er for lang til at være pålidelig.</translation>
<translation id="7087282848513945231">Amt/region</translation>
-<translation id="7108649287766967076">Oversættelsen til <ph name="TARGET_LANGUAGE"/> mislykkedes.</translation>
+<translation id="7108649287766967076">Oversættelsen til <ph name="TARGET_LANGUAGE" /> mislykkedes.</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7179921470347911571">Genstart nu</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="7186367841673660872">Denne side er oversat fra<ph name="ORIGINAL_LANGUAGE" />til<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Søg på <ph name="SITE_NAME"/> efter <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Søg på <ph name="SITE_NAME" /> efter <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Der kunne ikke oprettes en privat forbindelse til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, da dato og tid (<ph name="DATE_AND_TIME" />) på din enhed er forkerte.</translation>
<translation id="7275334191706090484">Administrerede bogmærker</translation>
<translation id="7298195798382681320">Anbefalet</translation>
<translation id="7334320624316649418">&amp;Annuller fortryd omarrangering</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obligatorisk</translation>
<translation id="7542995811387359312">Automatisk udfyldning af kreditkort er deaktiveret, fordi formularen ikke bruger en sikker forbindelse.</translation>
-<translation id="7568593326407688803">Denne side er på<ph name="ORIGINAL_LANGUAGE"/>Vil du oversætte den?</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="7568593326407688803">Denne side er på<ph name="ORIGINAL_LANGUAGE" />Vil du oversætte den?</translation>
<translation id="7569952961197462199">Vil du fjerne kreditkortet fra Chrome?</translation>
-<translation id="7600965453749440009">Oversæt aldrig <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Værdien er uden for intervallet <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Begrænsningerne for serverens certifikatnavn er overtrådt.</translation>
+<translation id="7600965453749440009">Oversæt aldrig <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Værdien er uden for intervallet <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Er du interesseret i smarte nye Chrome-funktioner? Prøv vores udviklerkanal på chrome.com/dev.</translation>
<translation id="7752995774971033316">Administreres ikke</translation>
+<translation id="7761701407923456692">Serverens certifikat passer ikke til webadressen.</translation>
<translation id="777702478322588152">Præfektur</translation>
<translation id="7791543448312431591">Tilføj</translation>
<translation id="7805768142964895445">Status</translation>
<translation id="7813600968533626083">Vil du fjerne formularforslaget fra Chrome?</translation>
<translation id="7887683347370398519">Kontrollér, om din kontrolkode er korrekt, og prøv igen.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Serverens certifikatet er endnu ikke gyldigt.</translation>
<translation id="7956713633345437162">Bogmærker på mobil</translation>
<translation id="7961015016161918242">Aldrig</translation>
<translation id="7977590112176369853">&lt;indtast forespørgsel&gt;</translation>
-<translation id="7983301409776629893">Oversæt altid <ph name="ORIGINAL_LANGUAGE"/> til <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Oversæt altid <ph name="ORIGINAL_LANGUAGE" /> til <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Bogmærker på pc</translation>
<translation id="7995512525968007366">Ikke angivet</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="8003882219468422867">Virksomhedstilsidesættelse</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="8088680233425245692">Artiklen kunne ikke vises.</translation>
<translation id="8091372947890762290">Aktivering afventer serveren</translation>
<translation id="8194797478851900357">&amp;Fortryd flytning</translation>
-<translation id="8201077131113104583">Ugyldig webadresse til opdatering for udvidelse med id'et &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">Ugyldig webadresse til opdatering for udvidelse med id'et "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Gem ikke</translation>
<translation id="8218327578424803826">Tildelt placering:</translation>
<translation id="8249320324621329438">Sidste hentet:</translation>
+<translation id="8294431847097064396">Kilde</translation>
<translation id="8308427013383895095">Oversættelsen mislykkedes på grund af problemer med netværksforbindelsen.</translation>
<translation id="8311778656528046050">Er du sikker på, at du vil genindlæse denne side?</translation>
<translation id="8349305172487531364">Bogmærkelinje</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Gælder for</translation>
<translation id="8530504477309582336">Denne korttype understøttes ikke af Google Payments. Vælg et andet kort.</translation>
<translation id="8553075262323480129">Oversættelsen mislykkedes, fordi sidens sprog ikke kunne fastslås.</translation>
-<translation id="8571890674111243710">Oversætter siden til <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Der kan ikke oprettes en privat forbindelse til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, da tid og dato (<ph name="DATE_AND_TIME" />) på din enhed er forkerte.</translation>
+<translation id="8571890674111243710">Oversætter siden til <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Nulstil alle til standard</translation>
<translation id="8713130696108419660">Ugyldig første signatur</translation>
<translation id="8725066075913043281">Forsøg igen</translation>
+<translation id="8738058698779197622">For at kunne oprette en sikker forbindelse skal dit ur være indstillet korrekt. Det er vigtigt, da de certifikater, som websites bruger til at identificere sig selv, kun er gyldige i bestemte tidsperioder. Da uret på din enhed går forkert, kan Chromium ikke bekræfte disse certifikater.</translation>
<translation id="8790007591277257123">&amp;Annuller fortryd sletning</translation>
<translation id="8804164990146287819">Privatlivspolitik</translation>
+<translation id="8820817407110198400">Bogmærker</translation>
<translation id="8824019021993735287">Chrome kunne ikke bekræfte dit kort på dette tidspunkt. Prøv igen senere.</translation>
<translation id="8834246243508017242">Aktivér autofyld med kontaktpersoner...</translation>
<translation id="883848425547221593">Andre bogmærker</translation>
+<translation id="884923133447025588">Der blev ikke fundet nogen funktion til tilbagekaldelse.</translation>
<translation id="8866481888320382733">Der opstod en fejl ved parsing af indstillinger for politik</translation>
<translation id="8876793034577346603">Netværkskonfiguration kunne ikke parses.</translation>
<translation id="8891727572606052622">Ugyldig proxytilstand.</translation>
-<translation id="8940229512486821554">Kør <ph name="EXTENSION_NAME"/>-kommandoen: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Dette eksperiment er ikke tilgængeligt på din platform.</translation>
+<translation id="8903921497873541725">Zoom ind</translation>
+<translation id="8932102934695377596">Dit ur er bagud</translation>
+<translation id="8940229512486821554">Kør <ph name="EXTENSION_NAME" />-kommandoen: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Serverens certifikat er udløbet.</translation>
<translation id="8988760548304185580">Indtast udløbsdatoen og den trecifrede kontrolkode, som ses på bagsiden af dit kort</translation>
-<translation id="9020542370529661692">Denne side er oversat til <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Markeringer, der gælder for hele systemet, kan kun indstilles af ejeren: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Denne side er oversat til <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Du har forsøgt at nå <ph name="DOMAIN" />, men serveren præsenterede et ugyldigt certifikat.</translation>
<translation id="9125941078353557812">Indtast den trecifrede kontrolkode, som ses på bagsiden af dit kort</translation>
<translation id="9137013805542155359">Vis oprindelig</translation>
<translation id="9148507642005240123">&amp;Fortryd redigering</translation>
<translation id="9154176715500758432">Bliv på denne side</translation>
<translation id="9170848237812810038">&amp;Fortryd</translation>
+<translation id="917450738466192189">Serverens certifikat er ugyldigt.</translation>
+<translation id="9187827965378254003">Der er desværre ingen tilgængelige eksperimenter.</translation>
<translation id="9207861905230894330">Artiklen kunne ikke tilføjes.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">RYD FORMULAREN</translation>
+<translation id="988159990683914416">Udviklerversion</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_de.xtb b/chromium/components/strings/components_strings_de.xtb
index 3a8f7a8f54f..a7e5c7a17e5 100644
--- a/chromium/components/strings/components_strings_de.xtb
+++ b/chromium/components/strings/components_strings_de.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="de">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="de">
+<translation id="1032854598605920125">Im Uhrzeigersinn drehen</translation>
<translation id="1055184225775184556">&amp;Hinzufügen rückgängig machen</translation>
<translation id="106701514854093668">Desktop-Lesezeichen</translation>
-<translation id="1103523840287552314"><ph name="LANGUAGE"/> immer übersetzen</translation>
+<translation id="1080116354587839789">An Breite anpassen</translation>
+<translation id="1103523840287552314"><ph name="LANGUAGE" /> immer übersetzen</translation>
<translation id="1113869188872983271">&amp;Neu anordnen rückgängig machen</translation>
<translation id="111844081046043029">Möchten Sie diese Seite wirklich verlassen?</translation>
<translation id="112840717907525620">Richtlinien-Cache einwandfrei</translation>
<translation id="1132774398110320017">AutoFill-Einstellungen für Chrome...</translation>
-<translation id="1152921474424827756">Rufen Sie eine <ph name="BEGIN_LINK"/>im Cache gespeicherte Kopie<ph name="END_LINK"/> von <ph name="URL"/> auf.</translation>
+<translation id="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="1152921474424827756">Rufen Sie eine <ph name="BEGIN_LINK" />im Cache gespeicherte Kopie<ph name="END_LINK" /> von <ph name="URL" /> auf.</translation>
+<translation id="121201262018556460">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, der Server hat jedoch ein Zertifikat mit einem schwachen Schlüssel übermittelt. Ein Hacker könnte den privaten Schlüssel geknackt haben, sodass es sich möglicherweise nicht um den erwarteten Server handelt, sondern Sie stattdessen mit einem Hacker kommunizieren.</translation>
<translation id="1227224963052638717">Unbekannte Richtlinie</translation>
<translation id="1227633850867390598">Wert ausblenden</translation>
<translation id="1228893227497259893">Falsche Entitätskennung</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Anmeldedomain:</translation>
<translation id="1344588688991793829">AutoFill-Einstellungen für Chromium...</translation>
<translation id="1426410128494586442">Ja</translation>
+<translation id="1430915738399379752">Drucken</translation>
<translation id="1455235771979731432">Beim Bestätigen Ihrer Karte ist ein Problem aufgetreten. Überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut.</translation>
<translation id="1491151370853475546">Diese Seite aktualisieren</translation>
<translation id="1549470594296187301">Für diese Funktion muss JavaScript aktiviert sein.</translation>
-<translation id="1639239467298939599">Wird geladen...</translation>
<translation id="1640180200866533862">Nutzerrichtlinien</translation>
<translation id="1644184664548287040">Die Netzwerkkonfiguration ist ungültig und konnte nicht importiert werden.</translation>
-<translation id="1693754753824026215">Die Seite auf <ph name="SITE"/> meldet:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat ist gestern abgelaufen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. Die Uhr Ihres Computers ist derzeit auf <ph name="CURRENT_DATE" /> eingestellt. Ist das korrekt? Falls nicht, stellen Sie die Uhr Ihres Systems richtig ein und aktualisieren Sie anschließend diese Seite.}other{Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat ist vor # Tagen abgelaufen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. Die Uhr Ihres Computers ist derzeit auf <ph name="CURRENT_DATE" /> eingestellt. Ist das korrekt? Falls nicht, stellen Sie die Uhr Ihres Systems richtig ein und aktualisieren Sie anschließend diese Seite.}}</translation>
+<translation id="168841957122794586">Das Serverzertifikat weist einen schwachen kryptografischen Schlüssel auf.</translation>
+<translation id="1693754753824026215">Die Seite auf <ph name="SITE" /> meldet:</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="1734864079702812349">American Express</translation>
+<translation id="1763864636252898013">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird vom Betriebssystem Ihres Geräts als nicht vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
<translation id="1821930232296380041">Anfrage oder Anfrageparameter ungültig</translation>
-<translation id="1853748787962613237">Der Artikel kann nicht angezeigt werden.</translation>
<translation id="1871208020102129563">Der Proxy ist zur Verwendung von festen Proxyservern konfiguriert, nicht zur Verwendung einer PAC-Skript-URL.</translation>
-<translation id="1875753206475436906">Heuristischer Typ: <ph name="HEURISTIC_TYPE"/>
- Servertyp: <ph name="SERVER_TYPE"/>
- Feldsignatur: <ph name="FIELD_SIGNATURE"/>
- Formularsignatur: <ph name="FORM_SIGNATURE"/>
- Test-ID: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Besuchen Sie die Seite <ph name="LINK"/>.</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/>-Lesezeichen</translation>
+<translation id="194030505837763158">Besuchen Sie die Seite <ph name="LINK" />.</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" />-Lesezeichen</translation>
<translation id="1973335181906896915">Fehler bei der Serialisierung</translation>
+<translation id="1974060860693918893">Erweitert</translation>
<translation id="2025186561304664664">Proxy ist auf automatische Konfiguration eingestellt.</translation>
<translation id="2025623846716345241">Aktualisieren bestätigen</translation>
-<translation id="2030481566774242610">Meinten Sie <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Meinten Sie <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Postleitzahl</translation>
<translation id="20817612488360358">Die System-Proxy-Einstellungen sind zur Verwendung angegeben, gleichzeitig wurde aber auch eine explizite Proxy-Konfiguration festgelegt.</translation>
<translation id="2094505752054353250">Domains stimmen nicht überein.</translation>
<translation id="2096368010154057602">Verwaltungsbezirk</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="2114841414352855701">Wird ignoriert, da sie von <ph name="POLICY_NAME" /> außer Kraft gesetzt wurde.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Mobile Lesezeichen</translation>
+<translation id="2171101176734966184">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, der Server hat jedoch ein Zertifikat übermittelt, das einen schwachen Signaturalgorithmus verwendet. Das bedeutet, dass die vom Server übermittelten Sicherheitsinformationen gefälscht sein könnten und es sich möglicherweise gar nicht um den erwarteten Server handelt, sondern Sie mit einem Hacker kommunizieren.</translation>
<translation id="2181821976797666341">Richtlinien</translation>
<translation id="2212735316055980242">Richtlinie nicht gefunden</translation>
<translation id="2213606439339815911">Einträge werden abgerufen...</translation>
<translation id="225207911366869382">Dieser Wert für die Richtlinie ist veraltet.</translation>
<translation id="2262243747453050782">HTTP-Fehler</translation>
-<translation id="2270192940992995399">Der Artikel wurde nicht gefunden.</translation>
-<translation id="2328300916057834155">Ungültiges Lesezeichen bei Index <ph name="ENTRY_INDEX"/> ignoriert</translation>
+<translation id="2282872951544483773">Nicht verfügbare Experimente</translation>
+<translation id="229702904922032456">Ein Stamm- oder Zwischenzertifikat ist abgelaufen.</translation>
+<translation id="2328300916057834155">Ungültiges Lesezeichen bei Index <ph name="ENTRY_INDEX" /> ignoriert</translation>
<translation id="2354001756790975382">Weitere Lesezeichen</translation>
<translation id="2359808026110333948">Weiter</translation>
<translation id="2367567093518048410">Ebene</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="2396249848217231973">&amp;Löschen rückgängig machen</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="2455981314101692989">Auf dieser Webseite ist die AutoFill-Funktion für das Formular deaktiviert.</translation>
<translation id="2479410451996844060">Ungültige Such-URL</translation>
+<translation id="2491120439723279231">Das Serverzertifikat enthält Fehler.</translation>
<translation id="2495083838625180221">JSON-Parser</translation>
<translation id="2498091847651709837">Neue Karte scannen</translation>
<translation id="2556876185419854533">&amp;Bearbeiten rückgängig machen</translation>
-<translation id="2581221116934462656">Soll in <ph name="PRODUCT_NAME"/> ab dem nächsten Aufruf eine Übersetzung von Seiten dieser Website angeboten werden, die auf <ph name="LANGUAGE_NAME"/> sind?</translation>
+<translation id="2581221116934462656">Soll in <ph name="PRODUCT_NAME" /> ab dem nächsten Aufruf eine Übersetzung von Seiten dieser Website angeboten werden, die auf <ph name="LANGUAGE_NAME" /> sind?</translation>
<translation id="2587841377698384444">Directory API-ID:</translation>
<translation id="2597378329261239068">Dieses Dokument ist passwortgeschützt. Geben Sie ein Passwort ein.</translation>
+<translation id="2625385379895617796">Ihre Uhr geht vor.</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2653659639078652383">Senden</translation>
<translation id="2704283930420550640">Wert stimmt nicht mit dem Format überein.</translation>
<translation id="2721148159707890343">Anfrage erfolgreich</translation>
+<translation id="2728127805433021124">Das Serverzertifikat ist mit einem schwachen Signaturalgorithmus signiert.</translation>
<translation id="2774256287122201187">Sie können zu der Seite gehen. In diesem Fall wird diese Warnung fünf Minuten lang nicht mehr angezeigt.</translation>
<translation id="277499241957683684">Fehlender Gerätedatensatz</translation>
<translation id="2835170189407361413">Formular leeren</translation>
-<translation id="2855922900409897335"><ph name="CREDIT_CARD"/> bestätigen</translation>
+<translation id="2855922900409897335"><ph name="CREDIT_CARD" /> bestätigen</translation>
+<translation id="2915500479781995473">Dieser Server konnte nicht nachweisen, dass es sich dabei um <ph name="DOMAIN" /> handelt, da das Sicherheitszertifikat abgelaufen ist. Der Grund hierfür könnte eine fehlerhafte Konfiguration oder ein Angreifer sein, der Ihre Verbindung abfängt. Die Uhr Ihres Computers zeigt derzeit <ph name="CURRENT_TIME" /> an. Ist das korrekt? Falls nicht, stellen Sie die Uhr Ihres Systems richtig ein und aktualisieren Sie dann diese Seite.</translation>
+<translation id="2922350208395188000">Das Serverzertifikat kann nicht überprüft werden.</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="2958431318199492670">Die Netzwerkkonfiguration stimmt nicht mit dem ONC-Standard überein. Die Konfiguration wird unter Umständen nicht vollständig importiert.</translation>
<translation id="2972581237482394796">&amp;Wiederholen</translation>
-<translation id="3010559122411665027">Listeneintrag &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Listeneintrag "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Falscher Richtlinientyp</translation>
<translation id="3105172416063519923">Geräte-ID:</translation>
<translation id="3145945101586104090">Fehler beim Dekodieren der Antwort</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Insel</translation>
<translation id="3219579145727097045">Geben Sie das Ablaufdatum und den vierstelligen CVC-Code auf der Vorderseite Ihrer Karte ein.</translation>
-<translation id="3228969707346345236">Die Übersetzung ist fehlgeschlagen, weil die Seite bereits auf <ph name="LANGUAGE"/> ist.</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="3228969707346345236">Die Übersetzung ist fehlgeschlagen, weil die Seite bereits auf <ph name="LANGUAGE" /> ist.</translation>
<translation id="3270847123878663523">&amp;Neu anordnen rückgängig machen</translation>
+<translation id="3286538390144397061">Jetzt neu starten</translation>
<translation id="333371639341676808">Diese Seite am Erstellen zusätzlicher Dialoge hindern</translation>
-<translation id="3369366829301677151"><ph name="CREDIT_CARD"/> aktualisieren und bestätigen</translation>
+<translation id="3340978935015468852">Einstellungen</translation>
+<translation id="3369192424181595722">Fehler bei der Uhrzeit</translation>
+<translation id="3369366829301677151"><ph name="CREDIT_CARD" /> aktualisieren und bestätigen</translation>
<translation id="337363190475750230">Bereitstellung aufgehoben</translation>
<translation id="3377188786107721145">Fehler beim Parsen der Richtlinie</translation>
<translation id="3380365263193509176">Unbekannter Fehler</translation>
<translation id="3380864720620200369">Client-ID:</translation>
<translation id="3427342743765426898">&amp;Bearbeiten wiederholen</translation>
+<translation id="3435896845095436175">Aktivieren</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Abrufintervall:</translation>
+<translation id="3462200631372590220">Erweiterte Informationen ausblenden</translation>
+<translation id="3528171143076753409">Serverzertifikat ist nicht vertrauenswürdig.</translation>
<translation id="3542684924769048008">Passwort verwenden für:</translation>
<translation id="3583757800736429874">&amp;Verschieben wiederholen</translation>
<translation id="3623476034248543066">Wert zeigen</translation>
+<translation id="3648607100222897006">Diese experimentellen Funktionen können sich jederzeit ändern, abstürzen oder deaktiviert werden. Wir übernehmen keinerlei Gewährleistung für die Folgen der Aktivierung eines dieser Experimente. Es ist sogar möglich, dass Ihr Browser spontan in Flammen aufgeht. Spaß beiseite: Es ist möglich, dass Ihr Browser alle Ihre Daten löscht. Möglicherweise werden auch Ihre Sicherheits- und Datenschutzeinstellungen auf unerwartete Weise manipuliert. Alle von Ihnen aktivierten Experimente werden für alle Nutzer dieses Browsers aktiviert. Seien Sie also vorsichtig, wenn Sie fortfahren.</translation>
<translation id="3650584904733503804">Überprüfung erfolgreich</translation>
<translation id="370665806235115550">Wird geladen...</translation>
<translation id="3712624925041724820">Lizenzen aufgebraucht</translation>
<translation id="3739623965217189342">Von Ihnen kopierter Link</translation>
<translation id="375403751935624634">Aufgrund eines Serverfehlers ist die Übersetzung fehlgeschlagen.</translation>
<translation id="385051799172605136">Zurück</translation>
+<translation id="3858027520442213535">Datum und Uhrzeit aktualisieren</translation>
<translation id="3884278016824448484">In Konflikt stehende Gerätekennung</translation>
<translation id="3885155851504623709">Gemeinde</translation>
<translation id="3934680773876859118">Fehler beim Laden des PDF-Dokuments</translation>
<translation id="3963721102035795474">Lesemodus</translation>
<translation id="4030383055268325496">&amp;Hinzufügen rückgängig machen</translation>
-<translation id="4058922952496707368">Schlüssel &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">Warnung</translation>
+<translation id="4058922952496707368">Schlüssel "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Die Proxy-Konfiguration ist auf die Verwendung einer PAC-Skript-URL und nicht die von festen Proxyservern eingestellt.</translation>
<translation id="409504436206021213">Nicht aktualisieren</translation>
<translation id="4103249731201008433">Seriennummer des Geräts ist ungültig.</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Fehlerhafte Signatur</translation>
<translation id="4269787794583293679">(Kein Nutzername)</translation>
<translation id="4300246636397505754">Vorschläge für Eltern</translation>
-<translation id="4372948949327679948">Erwarteter <ph name="VALUE_TYPE"/>-Wert</translation>
+<translation id="4325863107915753736">Der Artikel wurde nicht gefunden.</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="4394049700291259645">Deaktivieren</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="443673843213245140">Die Proxy-Nutzung ist deaktiviert, es ist jedoch eine explizite Proxy-Konfiguration festgelegt.</translation>
-<translation id="4506176782989081258">Fehler bei der Überprüfung: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Fehler bei der Überprüfung: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Adresse aus Chrome entfernen?</translation>
<translation id="4594403342090139922">&amp;Löschen rückgängig machen</translation>
<translation id="4607653538520819196">Datenkomprimierungs-Proxy kann für diese Seite nicht verwendet werden</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="4726672564094551039">Richtlinien neu laden</translation>
+<translation id="4728558894243024398">Plattform</translation>
+<translation id="4771973620359291008">Ein unbekannter Fehler ist aufgetreten.</translation>
<translation id="4800132727771399293">Prüfen Sie Ihr Ablaufdatum und Ihren CVC und versuchen Sie es dann erneut.</translation>
<translation id="4813512666221746211">Netzwerkfehler</translation>
+<translation id="4816492930507672669">An Seite anpassen</translation>
<translation id="4850886885716139402">Anzeigen</translation>
-<translation id="4923417429809017348">Diese Seite wurde von einer unbekannten Sprache in <ph name="LANGUAGE_LANGUAGE"/> übersetzt.</translation>
+<translation id="4923417429809017348">Diese Seite wurde von einer unbekannten Sprache in <ph name="LANGUAGE_LANGUAGE" /> übersetzt.</translation>
<translation id="4926049483395192435">Angabe erforderlich</translation>
<translation id="4968547170521245791">Proxynutzung nicht möglich</translation>
-<translation id="498957508165411911">Übersetzen (<ph name="ORIGINAL_LANGUAGE"/> &gt; <ph name="TARGET_LANGUAGE"/>)?</translation>
+<translation id="498957508165411911">Übersetzen (<ph name="ORIGINAL_LANGUAGE" /> &gt; <ph name="TARGET_LANGUAGE" />)?</translation>
<translation id="5019198164206649151">Sicherungsspeicher ist fehlerhaft.</translation>
<translation id="5031870354684148875">Über Google Übersetzer</translation>
+<translation id="5045550434625856497">Falsches Passwort</translation>
+<translation id="5087286274860437796">Das Serverzertifikat ist zurzeit ungültig.</translation>
<translation id="5089810972385038852">Bundesstaat/-land</translation>
+<translation id="5094747076828555589">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird von Chromium als nicht vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
<translation id="5095208057601539847">Provinz</translation>
<translation id="5145883236150621069">Fehlercode in der Richtlinienantwort</translation>
<translation id="5172758083709347301">Computer</translation>
-<translation id="5179510805599951267">Nicht auf <ph name="ORIGINAL_LANGUAGE"/>? Diesen Fehler melden</translation>
+<translation id="5179510805599951267">Nicht auf <ph name="ORIGINAL_LANGUAGE" />? Diesen Fehler melden</translation>
<translation id="5190835502935405962">Lesezeichenleiste</translation>
+<translation id="5199729219167945352">Experimente</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">Navigation bestätigen</translation>
<translation id="5299298092464848405">Fehler beim Parsen der Richtlinie</translation>
+<translation id="5316812925700871227">Gegen den Uhrzeigersinn drehen</translation>
<translation id="5317780077021120954">Speichern</translation>
<translation id="536296301121032821">Fehler beim Speichern der Richtlinieneinstellungen</translation>
-<translation id="5439770059721715174">Schemavalidierungsfehler in &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Schemavalidierungsfehler in "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Zeitstempel der Richtlinie ist fehlerhaft.</translation>
<translation id="5470861586879999274">&amp;Bearbeiten wiederholen</translation>
<translation id="5509780412636533143">Verwaltete Lesezeichen</translation>
<translation id="5523118979700054094">Richtlinienname</translation>
<translation id="552553974213252141">Wurde der Text korrekt extrahiert?</translation>
<translation id="5540224163453853">Der gewünschte Artikel wurde nicht gefunden.</translation>
+<translation id="5556459405103347317">Neu laden</translation>
<translation id="5565735124758917034">Aktiv</translation>
<translation id="560412284261940334">Verwaltung wird nicht unterstützt.</translation>
<translation id="5629630648637658800">Fehler beim Laden der Richtlinieneinstellungen</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Aktueller Nutzer</translation>
<translation id="5813119285467412249">&amp;Hinzufügen wiederholen</translation>
<translation id="5872918882028971132">Vorschläge für Eltern</translation>
-<translation id="587701087903783706">Für Mobilgeräte optimierte Ansicht schließen</translation>
<translation id="59107663811261420">Dieser Kartentyp wird von Google Payments für diesen Händler nicht unterstützt. Bitte verwenden Sie eine andere Karte.</translation>
+<translation id="5975083100439434680">Verkleinern</translation>
<translation id="5989320800837274978">Weder feste Proxyserver noch eine PAC-Skript-URL sind festgelegt.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Schließen</translation>
+<translation id="6060685159320643512">Vorsichtig, diese Experimente können gefährlich sein!</translation>
+<translation id="6151417162996330722">Die Gültigkeitsdauer des Serverzertifikats ist zu lang.</translation>
<translation id="6154808779448689242">Zurückgegebenes Token der Richtlinie entspricht nicht dem aktuellen Token.</translation>
<translation id="6165508094623778733">Weitere Informationen</translation>
<translation id="6259156558325130047">&amp;Neu anordnen rückgängig machen</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/>-Lesezeichen</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" />-Lesezeichen</translation>
<translation id="6282194474023008486">Postleitzahl</translation>
<translation id="6337534724793800597">Richtlinien nach Name filtern</translation>
+<translation id="6387478394221739770">Interessiert an coolen neuen Chrome-Funktionen? Testen Sie unsere Betaversion unter chrome.com/beta.</translation>
+<translation id="6426993025560594914">Alle Experimente sind auf Ihrer Plattform verfügbar.</translation>
<translation id="6445051938772793705">Land</translation>
<translation id="6458467102616083041">Ignoriert, da Standardsuche durch Richtlinie deaktiviert</translation>
<translation id="647261751007945333">Geräterichtlinien</translation>
<translation id="6512448926095770873">Diese Seite verlassen</translation>
<translation id="6529602333819889595">&amp;Löschen wiederholen</translation>
<translation id="6550675742724504774">Optionen</translation>
-<translation id="6597614308054261376">Sie versuchen, <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> zu erreichen. Für diese Seite kann der Datenkomprimierungs-Proxy derzeit nicht verwendet werden.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/>-Suche</translation>
+<translation id="6597614308054261376">Sie versuchen, <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> zu erreichen. Für diese Seite kann der Datenkomprimierungs-Proxy derzeit nicht verwendet werden.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" />-Suche</translation>
<translation id="6644283850729428850">Diese Richtlinie ist veraltet.</translation>
<translation id="6646897916597483132">Geben Sie den vierstelligen CVC-Code auf der Vorderseite Ihrer Karte ein.</translation>
+<translation id="674375294223700098">Fehler wegen unbekanntem Serverzertifikat</translation>
<translation id="6753269504797312559">Wert der Richtlinie</translation>
<translation id="6831043979455480757">Übersetzen</translation>
<translation id="6839929833149231406">Stadtteil</translation>
<translation id="6874604403660855544">&amp;Hinzufügen wiederholen</translation>
<translation id="6891596781022320156">Richtlinienebene wird nicht unterstützt.</translation>
<translation id="6915804003454593391">Nutzer:</translation>
+<translation id="6957887021205513506">Das Zertifikat des Servers ist möglicherweise eine Fälschung.</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="6980028882292583085">JavaScript-Warnmeldung</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Sie haben versucht, <ph name="DOMAIN" /> zu erreichen. Der Server hat jedoch ein Zertifikat präsentiert, dessen Gültigkeitsdauer zu lang ist, um vertrauenswürdig zu sein.</translation>
<translation id="7087282848513945231">Landkreis</translation>
-<translation id="7108649287766967076">Bei der Übersetzung (<ph name="TARGET_LANGUAGE"/>) ist ein Fehler aufgetreten.</translation>
+<translation id="7108649287766967076">Bei der Übersetzung (<ph name="TARGET_LANGUAGE" />) ist ein Fehler aufgetreten.</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7179921470347911571">Jetzt neu starten</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="7186367841673660872">Diese Seite wurde von<ph name="ORIGINAL_LANGUAGE" />in<ph name="LANGUAGE_LANGUAGE" />übersetzt.</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531"><ph name="SITE_NAME"/> nach <ph name="SEARCH_TERMS"/> durchsuchen</translation>
+<translation id="7208899522964477531"><ph name="SITE_NAME" /> nach <ph name="SEARCH_TERMS" /> durchsuchen</translation>
+<translation id="725866823122871198">Es kann keine private Verbindung zu <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hergestellt werden, weil Datum und Uhrzeit Ihres Computers falsch sind (<ph name="DATE_AND_TIME" />).</translation>
<translation id="7275334191706090484">Verwaltete Lesezeichen</translation>
<translation id="7298195798382681320">Empfohlen</translation>
<translation id="7334320624316649418">&amp;Neu anordnen wiederholen</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Verbindlich</translation>
<translation id="7542995811387359312">Die Funktion zur automatischen Ausfüllung der Kreditkartendaten ist deaktiviert, da dieses Formular keine sichere Verbindung nutzt.</translation>
-<translation id="7568593326407688803">Diese Seite ist auf<ph name="ORIGINAL_LANGUAGE"/>Soll sie übersetzt werden?</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="7568593326407688803">Diese Seite ist auf<ph name="ORIGINAL_LANGUAGE" />Soll sie übersetzt werden?</translation>
<translation id="7569952961197462199">Kreditkarte aus Chrome entfernen?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/> nie übersetzen</translation>
-<translation id="7610193165460212391">Wert liegt außerhalb des zulässigen Bereichs (<ph name="VALUE"/>).</translation>
+<translation id="7592362899630581445">Das Serverzertifikat verstößt gegen Namensbeschränkungen.</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" /> nie übersetzen</translation>
+<translation id="7610193165460212391">Wert liegt außerhalb des zulässigen Bereichs (<ph name="VALUE" />).</translation>
+<translation id="7674629440242451245">Interessiert an coolen neuen Chrome-Funktionen? Testen Sie unsere Dev-Version unter chrome.com/dev.</translation>
<translation id="7752995774971033316">Nicht verwaltet</translation>
+<translation id="7761701407923456692">Das Serverzertifikat stimmt nicht mit der URL überein.</translation>
<translation id="777702478322588152">Präfektur</translation>
<translation id="7791543448312431591">Hinzufügen</translation>
<translation id="7805768142964895445">Status</translation>
<translation id="7813600968533626083">Vorschlag für das Formular aus Chrome entfernen?</translation>
<translation id="7887683347370398519">Prüfen Sie Ihren CVC und versuchen Sie es dann erneut.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Serverzertifikat ist noch nicht gültig.</translation>
<translation id="7956713633345437162">Mobile Lesezeichen</translation>
<translation id="7961015016161918242">Nie</translation>
<translation id="7977590112176369853">&lt;Suchanfrage eingeben&gt;</translation>
-<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE"/> immer auf <ph name="TARGET_LANGUAGE"/> übersetzen</translation>
+<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE" /> immer auf <ph name="TARGET_LANGUAGE" /> übersetzen</translation>
<translation id="7988324688042446538">Desktop-Lesezeichen</translation>
<translation id="7995512525968007366">Nicht angegeben</translation>
-<translation id="8034522405403831421">Diese Seite ist auf <ph name="SOURCE_LANGUAGE"/>. In folgende Sprache übersetzen: <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Überschreibung durch Unternehmen</translation>
+<translation id="8034522405403831421">Diese Seite ist auf <ph name="SOURCE_LANGUAGE" />. In folgende Sprache übersetzen: <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Der Artikel kann nicht angezeigt werden.</translation>
<translation id="8091372947890762290">Aktivierung auf dem Server steht noch aus.</translation>
<translation id="8194797478851900357">&amp;Verschieben rückgängig machen</translation>
-<translation id="8201077131113104583">Ungültige Update-URL für Erweiterung mit der ID &quot;<ph name="EXTENSION_ID"/>&quot;</translation>
+<translation id="8201077131113104583">Ungültige Update-URL für Erweiterung mit der ID "<ph name="EXTENSION_ID" />"</translation>
<translation id="8208216423136871611">Nicht speichern</translation>
<translation id="8218327578424803826">Zugewiesener Standort:</translation>
<translation id="8249320324621329438">Letzter Abruf:</translation>
+<translation id="8294431847097064396">Quelle</translation>
<translation id="8308427013383895095">Die Übersetzung ist aufgrund eines Problems mit der Netzwerkverbindung fehlgeschlagen.</translation>
<translation id="8311778656528046050">Möchten Sie diese Seite wirklich aktualisieren?</translation>
<translation id="8349305172487531364">Lesezeichenleiste</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Gilt für</translation>
<translation id="8530504477309582336">Dieser Kartentyp wird von Google Payments nicht unterstützt. Bitte verwenden Sie eine andere Karte.</translation>
<translation id="8553075262323480129">Die Übersetzung ist fehlgeschlagen, weil die Sprache der Seite nicht ermittelt werden konnte.</translation>
-<translation id="8571890674111243710">Seite wird in folgende Sprache übersetzt: <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Es kann keine private Verbindung zu <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hergestellt werden, weil Datum und Uhrzeit Ihres Geräts falsch sind (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="8571890674111243710">Seite wird in folgende Sprache übersetzt: <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Alle auf Standardeinstellung zurücksetzen</translation>
<translation id="8713130696108419660">Erste Signatur ungültig</translation>
<translation id="8725066075913043281">Erneut versuchen</translation>
+<translation id="8738058698779197622">Zum Aufbau einer sicheren Verbindung muss die Uhrzeit richtig eingestellt sein. Der Grund hierfür ist, dass Websites sich mithilfe von Zertifikaten identifizieren, die nur für einen bestimmten Zeitraum gelten. Da die Uhrzeit Ihres Geräts falsch ist, kann Chromium diese Zertifikate nicht bestätigen.</translation>
<translation id="8790007591277257123">&amp;Löschen wiederholen</translation>
<translation id="8804164990146287819">Datenschutzerklärung</translation>
+<translation id="8820817407110198400">Lesezeichen</translation>
<translation id="8824019021993735287">Ihre Karte konnte momentan nicht überprüft werden. Bitte versuchen Sie es später erneut.</translation>
<translation id="8834246243508017242">AutoFill aktivieren und dazu die Kontakte verwenden…</translation>
<translation id="883848425547221593">Andere Lesezeichen</translation>
+<translation id="884923133447025588">Kein Sperrmechanismus gefunden.</translation>
<translation id="8866481888320382733">Fehler beim Parsen der Richtlinieneinstellungen</translation>
<translation id="8876793034577346603">Fehler beim Parsen der Netzwerkkonfiguration</translation>
<translation id="8891727572606052622">Ungültiger Proxy-Modus</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/>-Befehl ausführen: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Leider steht dieses Experiment auf Ihrer Plattform nicht zur Verfügung.</translation>
+<translation id="8903921497873541725">Vergrößern</translation>
+<translation id="8932102934695377596">Ihre Uhr geht nach.</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" />-Befehl ausführen: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Das Serverzertifikat ist abgelaufen.</translation>
<translation id="8988760548304185580">Geben Sie das Ablaufdatum und den dreistelligen CVC-Code auf der Rückseite Ihrer Karte ein.</translation>
-<translation id="9020542370529661692">Die Seite wurde übersetzt und liegt nun auf <ph name="TARGET_LANGUAGE"/> vor.</translation>
+<translation id="901974403500617787">Parameter, die systemweit gelten, können nur vom Eigentümer festgelegt werden: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Die Seite wurde übersetzt und liegt nun auf <ph name="TARGET_LANGUAGE" /> vor.</translation>
+<translation id="9049981332609050619">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, der Server hat sich jedoch mit einem ungültigen Zertifikat ausgewiesen.</translation>
<translation id="9125941078353557812">Geben Sie den dreistelligen CVC-Code auf der Rückseite Ihrer Karte ein.</translation>
<translation id="9137013805542155359">Original anzeigen</translation>
<translation id="9148507642005240123">&amp;Bearbeiten rückgängig machen</translation>
<translation id="9154176715500758432">Auf dieser Seite bleiben</translation>
<translation id="9170848237812810038">&amp;Rückgängig</translation>
+<translation id="917450738466192189">Das Serverzertifikat ist ungültig.</translation>
+<translation id="9187827965378254003">Leider sind zurzeit keine Experimente verfügbar.</translation>
<translation id="9207861905230894330">Der Artikel konnte nicht hinzugefügt werden.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">Formular leeren</translation>
+<translation id="988159990683914416">Entwickler-Build</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_el.xtb b/chromium/components/strings/components_strings_el.xtb
index a37b2b455ef..0ad2f9fca5f 100644
--- a/chromium/components/strings/components_strings_el.xtb
+++ b/chromium/components/strings/components_strings_el.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="el">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="el">
+<translation id="1032854598605920125">Περιστροφή προς τα δεξιά</translation>
<translation id="1055184225775184556">&amp;Αναίρεση προσθήκης</translation>
<translation id="106701514854093668">Σελιδοδείκτες επιτραπέζιου υπολογιστή</translation>
-<translation id="1103523840287552314">Να μεταφράζονται πάντα τα <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Προσαρμογή στο πλάτος</translation>
+<translation id="1103523840287552314">Να μεταφράζονται πάντα τα <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Αναίρεση αναδιάταξης</translation>
<translation id="111844081046043029">Είστε βέβαιοι ότι επιθυμείτε έξοδο από αυτή τη σελίδα;</translation>
<translation id="112840717907525620">Η προσωρινή μνήμη της πολιτικής είναι εντάξει</translation>
<translation id="1132774398110320017">Ρυθμίσεις Αυτόματης συμπλήρωσης Chrome…</translation>
-<translation id="1152921474424827756">Πρόσβαση σε <ph name="BEGIN_LINK"/>προσωρινό αντίγραφο<ph name="END_LINK"/> της διεύθυνσης <ph name="URL"/></translation>
+<translation id="1150979032973867961">Ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωρείται έμπιστο από το λειτουργικό σύστημα της συσκευής σας. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
+<translation id="1152921474424827756">Πρόσβαση σε <ph name="BEGIN_LINK" />προσωρινό αντίγραφο<ph name="END_LINK" /> της διεύθυνσης <ph name="URL" /></translation>
+<translation id="121201262018556460">Προσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, αλλά ο διακομιστής παρουσίασε ένα πιστοποιητικό που περιέχει ένα αδύναμο κλειδί. Κάποιος εισβολέας θα μπορούσε να έχει παραβιάσει το ιδιωτικό κλειδί και ο διακομιστής ενδέχεται να μην είναι ο διακομιστής που αναμένατε (μπορεί να επικοινωνείτε με έναν εισβολέα).</translation>
<translation id="1227224963052638717">Άγνωστη πολιτική.</translation>
<translation id="1227633850867390598">Απόκρυψη τιμής</translation>
<translation id="1228893227497259893">Εσφαλμένο αναγνωριστικό οντότητας</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Τομέας εγγραφής:</translation>
<translation id="1344588688991793829">Ρυθμίσεις αυτόματης συμπλήρωσης Chromium…</translation>
<translation id="1426410128494586442">Ναι</translation>
+<translation id="1430915738399379752">Εκτύπωση</translation>
<translation id="1455235771979731432">Παρουσιάστηκε ένα πρόβλημα με την επαλήθευση της κάρτας σας. Ελέγξτε τη σύνδεσή σας στο διαδίκτυο και δοκιμάστε ξανά.</translation>
<translation id="1491151370853475546">Εκ νέου φόρτωση αυτής της σελίδας</translation>
<translation id="1549470594296187301">Θα πρέπει να ενεργοποιηθεί η JavaScript για τη χρήση αυτής της λειτουργίας.</translation>
-<translation id="1639239467298939599">Γίνεται φόρτωση</translation>
<translation id="1640180200866533862">Πολιτικές χρηστών</translation>
<translation id="1644184664548287040">Η διαμόρφωση δικτύου είναι μη έγκυρη και δεν ήταν δυνατή η εισαγωγή της.</translation>
-<translation id="1693754753824026215">Ειδοποίηση από τη σελίδα στη διεύθυνση <ph name="SITE"/>:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Αυτός ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του έληξε χθες. Αυτό μπορεί να οφείλεται σε εσφαλμένη ρύθμιση ή σε κάποιον εισβολέα που παρεμβαίνει στη σύνδεσή σας. Το ρολόι του υπολογιστή σας αυτήν τη στιγμή είναι ρυθμισμένο στην ημερομηνία <ph name="CURRENT_DATE" />. Είναι σωστή αυτή η ρύθμιση; Εάν όχι, θα πρέπει να διορθώσετε το ρολόι του συστήματός σας και έπειτα να ανανεώσετε αυτήν τη σελίδα.}other{Αυτός ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του έληξε πριν από # ημέρες. Αυτό μπορεί να οφείλεται σε εσφαλμένη ρύθμιση ή σε κάποιον εισβολέα που παρεμβαίνει στη σύνδεσή σας. Το ρολόι του υπολογιστή σας αυτήν τη στιγμή είναι ρυθμισμένο στην ημερομηνία <ph name="CURRENT_DATE" />. Είναι σωστή αυτή η ρύθμιση; Εάν όχι, θα πρέπει να διορθώσετε το ρολόι του συστήματός σας και έπειτα να ανανεώσετε αυτήν τη σελίδα.}}</translation>
+<translation id="168841957122794586">Το πιστοποιητικό διακομιστή περιέχει ένα αδύναμο κρυπτογραφικό κλειδί.</translation>
+<translation id="1693754753824026215">Ειδοποίηση από τη σελίδα στη διεύθυνση <ph name="SITE" />:</translation>
+<translation id="1706954506755087368">{1,plural, =1{Αυτός ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Η ημερομηνία του πιστοποιητικού ασφαλείας του υποτίθεται ότι είναι αυριανή. Αυτό μπορεί να οφείλεται σε εσφαλμένη ρύθμιση ή σε κάποιον εισβολέα που παρεμβαίνει στη σύνδεσή σας.}other{Αυτός ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Η ημερομηνία του πιστοποιητικού ασφαλείας του υποτίθεται ότι είναι από # ημέρες μετά. Αυτό μπορεί να οφείλεται σε εσφαλμένη ρύθμιση ή σε κάποιον εισβολέα που παρεμβαίνει στη σύνδεσή σας.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωρείται έμπιστο από το λειτουργικό σύστημα της συσκευής σας. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
<translation id="1821930232296380041">Μη έγκυρο αίτημα ή παράμετροι αιτήματος</translation>
-<translation id="1853748787962613237">Αποτυχία εμφάνισης άρθρου.</translation>
<translation id="1871208020102129563">Ο διακομιστής μεσολάβησης έχει ρυθμιστεί να χρησιμοποιεί διακομιστές μεσολάβησης και όχι μια διεύθυνση URL σεναρίου .pac.</translation>
-<translation id="1875753206475436906">τύπος ευρετικού κανόνα: <ph name="HEURISTIC_TYPE"/>
- τύπος διακομιστή: <ph name="SERVER_TYPE"/>
- υπογραφή πεδίου: <ph name="FIELD_SIGNATURE"/>
- υπογραφή φόρμας: <ph name="FORM_SIGNATURE"/>
- αναγνωριστικό πειράματος: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Μετάβαση στο σύνδεσμο <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Σελιδοδείκτες <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Μετάβαση στο σύνδεσμο <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Σελιδοδείκτες <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Σφάλμα σειριοποίησης</translation>
+<translation id="1974060860693918893">Σύνθετες</translation>
<translation id="2025186561304664664">Ο διακομιστής μεσολάβησης έχει ρυθμιστεί σε αυτόματη διαμόρφωση.</translation>
<translation id="2025623846716345241">Επιβεβαίωση εκ νέου φόρτωσης</translation>
-<translation id="2030481566774242610">Μήπως εννοείτε <ph name="LINK"/>;</translation>
+<translation id="2030481566774242610">Μήπως εννοείτε <ph name="LINK" />;</translation>
<translation id="2053553514270667976">Ταχυδρομικός κώδικας</translation>
<translation id="20817612488360358">Οι ρυθμίσεις διακομιστή μεσολάβησης του συστήματος έχουν οριστεί για να χρησιμοποιηθούν, αλλά καθορίζεται επίσης μια ρητή διαμόρφωση του διακομιστή μεσολάβησης.</translation>
<translation id="2094505752054353250">Αναντιστοιχία τομέα</translation>
<translation id="2096368010154057602">Νομός</translation>
<translation id="2113977810652731515">Παιχνίδια με κάρτες</translation>
-<translation id="2114841414352855701">Αγνοήθηκε επειδή αντικαταστάθηκε από την πολιτική <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Αγνοήθηκε επειδή αντικαταστάθηκε από την πολιτική <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Σελιδοδείκτες κινητής συσκευής</translation>
+<translation id="2171101176734966184">Προσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, αλλά ο διακομιστής παρουσίασε ένα πιστοποιητικό το οποίο ήταν υπογεγραμμένο με έναν αδύναμο αλγόριθμο υπογραφής. Αυτό σημαίνει ότι μπορεί να έχουν πλαστογραφηθεί τα διαπιστευτήρια ασφαλείας που επέδειξε ο διακομιστής και ότι αυτός ο διακομιστής ενδέχεται να μην είναι αυτό που αναμένετε (ενδέχεται να επικοινωνείτε με έναν εισβολέα).</translation>
<translation id="2181821976797666341">Πολιτικές</translation>
<translation id="2212735316055980242">Η πολιτική δε βρέθηκε</translation>
<translation id="2213606439339815911">Ανάκτηση καταχωρίσεων…</translation>
<translation id="225207911366869382">Αυτή η πολιτική έχει καταργηθεί για τη συγκεκριμένη πολιτική.</translation>
<translation id="2262243747453050782">Σφάλμα HTTP</translation>
-<translation id="2270192940992995399">Αποτυχία εύρεσης άρθρου.</translation>
-<translation id="2328300916057834155">Μη έγκυρος σελιδοδείκτης στο ευρετήριο <ph name="ENTRY_INDEX"/> που παραβλέφθηκε</translation>
+<translation id="2282872951544483773">Μη διαθέσιμα πειράματα</translation>
+<translation id="229702904922032456">Ένα πιστοποιητικό ρίζας ή ένα ενδιάμεσο πιστοποιητικό έχει λήξει.</translation>
+<translation id="2328300916057834155">Μη έγκυρος σελιδοδείκτης στο ευρετήριο <ph name="ENTRY_INDEX" /> που παραβλέφθηκε</translation>
<translation id="2354001756790975382">Άλλοι σελιδοδείκτες</translation>
<translation id="2359808026110333948">Συνέχεια</translation>
<translation id="2367567093518048410">Επίπεδο</translation>
+<translation id="2384307209577226199">Προεπιλογή επιχείρησης</translation>
+<translation id="2386255080630008482">Το πιστοποιητικό του διακομιστή ανακλήθηκε.</translation>
<translation id="2392959068659972793">Εμφάνιση πολιτικών χωρίς τιμή που να έχει οριστεί.</translation>
<translation id="2396249848217231973">&amp;Αναίρεση διαγραφής</translation>
+<translation id="2413528052993050574">Ο διακομιστής δεν κατάφερε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του μπορεί να έχει ανακληθεί. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
<translation id="2455981314101692989">Σε αυτήν την ιστοσελίδα έχει απενεργοποιηθεί η αυτόματη συμπλήρωση για τη συγκεκριμένη φόρμα.</translation>
<translation id="2479410451996844060">Μη έγκυρη διεύθυνση URL αναζήτησης.</translation>
+<translation id="2491120439723279231">Το πιστοποιητικό του διακομιστή περιέχει σφάλματα.</translation>
<translation id="2495083838625180221">Συντακτικός αναλυτής JSON</translation>
<translation id="2498091847651709837">Σάρωση νέας κάρτας</translation>
<translation id="2556876185419854533">&amp;Αναίρεση επεξεργασίας</translation>
-<translation id="2581221116934462656">Θέλετε το <ph name="PRODUCT_NAME"/> να προσφέρει τη μετάφραση σελίδων στα <ph name="LANGUAGE_NAME"/> από αυτόν τον ιστότοπο την επόμενη φορά;</translation>
+<translation id="2581221116934462656">Θέλετε το <ph name="PRODUCT_NAME" /> να προσφέρει τη μετάφραση σελίδων στα <ph name="LANGUAGE_NAME" /> από αυτόν τον ιστότοπο την επόμενη φορά;</translation>
<translation id="2587841377698384444">Αναγνωριστικό API καταλόγου:</translation>
<translation id="2597378329261239068">Αυτό το έγγραφο προστατεύεται με κωδικό πρόσβασης. Πληκτρολογήστε έναν κωδικό πρόσβασης.</translation>
+<translation id="2625385379895617796">Το ρολόι σας πάει μπροστά</translation>
<translation id="2639739919103226564">Κατάσταση:</translation>
+<translation id="2653659639078652383">Υποβολή</translation>
<translation id="2704283930420550640">Η τιμή δεν συμφωνεί με τη μορφή.</translation>
<translation id="2721148159707890343">Το αίτημα ήταν επιτυχές</translation>
+<translation id="2728127805433021124">Το πιστοποιητικό του διακομιστή είναι υπογεγραμμένο με έναν αδύναμο αλγόριθμο υπογραφής.</translation>
<translation id="2774256287122201187">Μπορείτε να συνεχίσετε. Αν συνεχίσετε στη σελίδα, αυτή η προειδοποίηση δεν θα εμφανιστεί ξανά για πέντε λεπτά.</translation>
<translation id="277499241957683684">Λείπει κάποιο αρχείο συσκευής</translation>
<translation id="2835170189407361413">Διαγραφή φόρμας</translation>
-<translation id="2855922900409897335">Επαλήθευση της κάρτας <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Επαλήθευση της κάρτας <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Αυτός ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του έχει λήξει. Αυτό ίσως να οφείλεται σε λάθος διαμόρφωση ή σε έναν εισβολέα που επιτίθεται στη σύνδεσή σας. Αυτήν τη στιγμή, η ώρα του υπολογιστή σας έχει οριστεί σε <ph name="CURRENT_TIME" />. Είναι σωστό αυτό; Εάν όχι, θα πρέπει να διορθώσετε το ρολόι του συστήματός σας και έπειτα να ανανεώσετε αυτήν τη σελίδα.</translation>
+<translation id="2922350208395188000">Δεν είναι δυνατός ο έλεγχος του πιστοποιητικού του διακομιστή.</translation>
+<translation id="2941952326391522266">Ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του είναι από το <ph name="DOMAIN2" />. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
<translation id="2958431318199492670">Η διαμόρφωση δικτύου δεν συμμορφώνεται με το πρότυπο ONC. Ορισμένα τμήματα αυτής της διαμόρφωσης ενδέχεται να μην εισαχθούν.</translation>
<translation id="2972581237482394796">&amp;Επανάληψη ενέργειας</translation>
-<translation id="3010559122411665027">Καταχώριση λίστας &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Καταχώριση λίστας "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Λανθασμένος τύπος πολιτικής</translation>
<translation id="3105172416063519923">Αναγνωριστικό στοιχείο:</translation>
<translation id="3145945101586104090">Αποτυχία αποκωδικοποίησης απόκρισης</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Νησί</translation>
<translation id="3219579145727097045">Εισαγάγετε την ημερομηνία λήξης και τον τετραψήφιο κωδικό CVC από το μπροστινό μέρος της κάρτας σας</translation>
-<translation id="3228969707346345236">Η μετάφραση απέτυχε επειδή η σελίδα είναι ήδη στα <ph name="LANGUAGE"/>.</translation>
+<translation id="3225919329040284222">Ο διακομιστής παρουσίασε ένα πιστοποιητικό που δεν αντιστοιχεί στις ενσωματωμένες προϋποθέσεις. Αυτές οι προϋποθέσεις συμπεριλαμβάνονται σε συγκεκριμένους ιστότοπους υψηλής ασφάλειας για την προστασία σας.</translation>
+<translation id="3228969707346345236">Η μετάφραση απέτυχε επειδή η σελίδα είναι ήδη στα <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Αναίρεση αναδιάταξης</translation>
+<translation id="3286538390144397061">Άμεση επανεκκίνηση</translation>
<translation id="333371639341676808">Αποτροπή δημιουργίας πρόσθετων πλαισίων διαλόγου από αυτή τη σελίδα.</translation>
-<translation id="3369366829301677151">Ενημέρωση και επαλήθευση της κάρτας σας <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">ρυθμίσεις</translation>
+<translation id="3369192424181595722">Σφάλμα ρολογιού</translation>
+<translation id="3369366829301677151">Ενημέρωση και επαλήθευση της κάρτας σας <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Κατάργηση παροχής</translation>
<translation id="3377188786107721145">Σφάλμα ανάλυσης πολιτικής</translation>
<translation id="3380365263193509176">Άγνωστο σφάλμα</translation>
<translation id="3380864720620200369">Αναγνωριστικό πελάτη:</translation>
<translation id="3427342743765426898">&amp;Επανάληψη επεξεργασίας</translation>
+<translation id="3435896845095436175">Ενεργοποίηση</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Διάστημα ανάκτησης:</translation>
+<translation id="3462200631372590220">Απόκρυψη σύνθετων</translation>
+<translation id="3528171143076753409">Το πιστοποιητικό του διακομιστή δεν είναι αξιόπιστο.</translation>
<translation id="3542684924769048008">Χρήση κωδικού πρόσβασης για:</translation>
<translation id="3583757800736429874">&amp;Επανάληψη μετακίνησης</translation>
<translation id="3623476034248543066">Εμφάνιση τιμής</translation>
+<translation id="3648607100222897006">Αυτές οι πειραματικές λειτουργίες ενδέχεται να αλλάξουν, να διακοπούν ή να εξαφανιστούν οποιαδήποτε στιγμή. Δεν παρέχουμε καμία εγγύηση όσον αφορά τι θα συμβεί σε περίπτωση που ενεργοποιήσετε κάποια από αυτές, ενώ το πρόγραμμα περιήγησής σας ενδέχεται να παρουσιάσει σφάλμα, όπως να διαγράψει όλα τα δεδομένα σας. Επίσης, η ασφάλεια και το απόρρητο ενδέχεται να παραβιαστούν με μη αναμενόμενους τρόπους. Αν ενεργοποιήσετε κάποια πειραματική λειτουργία, η λειτουργία θα ενεργοποιηθεί για όλους τους χρήστες αυτού του προγράμματος περιήγησης. Συνεχίστε με προσοχή.</translation>
<translation id="3650584904733503804">Επιτυχής επικύρωση</translation>
<translation id="370665806235115550">Φόρτωση...</translation>
<translation id="3712624925041724820">Οι άδειες έχουν εξαντληθεί</translation>
<translation id="3739623965217189342">Σύνδεσμος που αντιγρ.</translation>
<translation id="375403751935624634">Η μετάφραση απέτυχε λόγω σφάλματος διακομιστή.</translation>
<translation id="385051799172605136">Πίσω</translation>
+<translation id="3858027520442213535">Ενημέρωση ημερομηνίας και ώρας</translation>
<translation id="3884278016824448484">Αναγνωριστικό συσκευής που προκαλεί διένεξη</translation>
<translation id="3885155851504623709">Ενορία</translation>
<translation id="3934680773876859118">Δεν ήταν δυνατή η φόρτωση του εγγράφου PDF</translation>
<translation id="3963721102035795474">Λειτουργία αναγνώστη</translation>
<translation id="4030383055268325496">&amp;Αναίρεση προσθήκης</translation>
-<translation id="4058922952496707368">Κλειδί &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ΠΡΟΕΙΔΟΠΟΙΗΣΗ</translation>
+<translation id="4058922952496707368">Κλειδί "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Η διαμόρφωση του διακομιστή μεσολάβησης είναι ορισμένη να χρησιμοποιεί μια διεύθυνση URL σεναρίου .pac και όχι σταθερούς διακομιστές μεσολάβησης.</translation>
<translation id="409504436206021213">Να μην γίνει εκ νέου φόρτωση</translation>
<translation id="4103249731201008433">Ο σειριακός αριθμός της συσκευής δεν είναι έγκυρος</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Εσφαλμένη υπογραφή</translation>
<translation id="4269787794583293679">(Χωρίς όνομα χρήστη)</translation>
<translation id="4300246636397505754">Γονικές προτάσεις</translation>
-<translation id="4372948949327679948">Αναμενόμενη τιμή <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Αποτυχία εύρεσης άρθρου</translation>
+<translation id="4372948949327679948">Αναμενόμενη τιμή <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Προσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, όμως το πιστοποιητικό που παρουσιάστηκε από το διακομιστή ανακλήθηκε από τον εκδότη του. Αυτό σημαίνει ότι τα διαπιστευτήρια ασφαλείας που παρουσιάστηκαν από το διακομιστή δεν πρέπει σε καμία περίπτωση να θεωρηθούν αξιόπιστα. Ενδέχεται να επικοινωνείτε με κάποιον εισβολέα.</translation>
+<translation id="4394049700291259645">Απενεργοποίηση</translation>
+<translation id="4424024547088906515">Ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωρείται έμπιστο από τον Chrome. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
<translation id="443673843213245140">Η χρήση ενός διακομιστή μεσολάβησης είναι απενεργοποιημένη, αλλά έχει καθοριστεί μια ρητή διαμόρφωση διακομιστή μεσολάβησης.</translation>
-<translation id="4506176782989081258">Σφάλμα επικύρωσης: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Σφάλμα επικύρωσης: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Κατάργηση διεύθυνσης από το Chrome;</translation>
<translation id="4594403342090139922">&amp;Αναίρεση διαγραφής</translation>
<translation id="4607653538520819196">Δεν είναι δυνατή η μεσολάβηση αυτής της σελίδας από την Εξοικονόμηση δεδομένων.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Ο διακομιστής δεν κατάφερε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του περιέχει σφάλματα. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
<translation id="4726672564094551039">Επανάληψη φόρτωσης πολιτικών</translation>
+<translation id="4728558894243024398">Πλατφόρμα</translation>
+<translation id="4771973620359291008">Παρουσιάστηκε άγνωστο σφάλμα.</translation>
<translation id="4800132727771399293">Ελέγξτε την ημερομηνία λήξης και τον κωδικό σας CVC και δοκιμάστε ξανά</translation>
<translation id="4813512666221746211">Σφάλμα δικτύου</translation>
+<translation id="4816492930507672669">Προσαρμογή στη σελίδα</translation>
<translation id="4850886885716139402">Προβολή</translation>
-<translation id="4923417429809017348">Αυτή η σελίδα έχει μεταφραστεί από μια άγνωστη γλώσσας στα <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Αυτή η σελίδα έχει μεταφραστεί από μια άγνωστη γλώσσας στα <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Πρέπει να καθοριστεί.</translation>
<translation id="4968547170521245791">Δεν είναι δυνατή η μεσολάβηση</translation>
-<translation id="498957508165411911">Μετάφραση των <ph name="ORIGINAL_LANGUAGE"/> στα <ph name="TARGET_LANGUAGE"/>;</translation>
+<translation id="498957508165411911">Μετάφραση των <ph name="ORIGINAL_LANGUAGE" /> στα <ph name="TARGET_LANGUAGE" />;</translation>
<translation id="5019198164206649151">Η αποθήκευση αντιγράφων ασφαλείας είναι σε κακή κατάσταση</translation>
<translation id="5031870354684148875">Σχετικά με τη Google Μετάφραση</translation>
+<translation id="5045550434625856497">Λανθασμένος κωδικός πρόσβασης</translation>
+<translation id="5087286274860437796">Το πιστοποιητικό του διακομιστή δεν είναι έγκυρο αυτήν τη στιγμή.</translation>
<translation id="5089810972385038852">Πολιτεία</translation>
+<translation id="5094747076828555589">Ο διακομιστής δεν μπορεί να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωρείται έμπιστο από το Chromium. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
<translation id="5095208057601539847">Επαρχία</translation>
<translation id="5145883236150621069">Βρέθηκε κωδικός σφάλματος στην απόκριση πολιτικής</translation>
<translation id="5172758083709347301">Υπολογιστής</translation>
-<translation id="5179510805599951267">Δεν είναι στα <ph name="ORIGINAL_LANGUAGE"/>; Αναφέρετε αυτό το σφάλμα</translation>
+<translation id="5179510805599951267">Δεν είναι στα <ph name="ORIGINAL_LANGUAGE" />; Αναφέρετε αυτό το σφάλμα</translation>
<translation id="5190835502935405962">Γραμμή σελιδοδεικτών</translation>
+<translation id="5199729219167945352">Πειράματα</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">Επιβεβαίωση περιήγησης</translation>
<translation id="5299298092464848405">Σφάλμα ανάλυσης πολιτικής</translation>
+<translation id="5316812925700871227">Περιστροφή προς τα αριστερά</translation>
<translation id="5317780077021120954">Αποθήκευση</translation>
<translation id="536296301121032821">Αποτυχία αποθήκευσης ρυθμίσεων πολιτικής</translation>
-<translation id="5439770059721715174">Σφάλμα επαλήθευσης σχήματος σε &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">Αυτός ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν είναι έγκυρο αυτήν τη στιγμή. Αυτό μπορεί να οφείλεται σε εσφαλμένη ρύθμιση ή σε κάποιον εισβολέα που παρεμβαίνει στη σύνδεσή σας.</translation>
+<translation id="5439770059721715174">Σφάλμα επαλήθευσης σχήματος σε "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Εσφαλμένη χρονική σήμανση πολιτικής</translation>
<translation id="5470861586879999274">&amp;Επανάληψη επεξεργασίας</translation>
<translation id="5509780412636533143">Διαχειριζόμενοι σελιδοδείκτες</translation>
<translation id="5523118979700054094">Όνομα πολιτικής</translation>
<translation id="552553974213252141">Έγινε σωστή εξαγωγή του κειμένου;</translation>
<translation id="5540224163453853">Δεν ήταν δυνατή η εύρεση του άρθρου που ζητήσατε.</translation>
+<translation id="5556459405103347317">Επαναφόρτωση</translation>
<translation id="5565735124758917034">Ενεργό</translation>
<translation id="560412284261940334">Η διαχείριση δεν υποστηρίζεται</translation>
<translation id="5629630648637658800">Αποτυχία φόρτωσης ρυθμίσεων πολιτικής</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Τρέχων χρήστης</translation>
<translation id="5813119285467412249">&amp;Επανάληψη προσθήκης</translation>
<translation id="5872918882028971132">Γονικές προτάσεις</translation>
-<translation id="587701087903783706">Κλείσιμο προβολής φιλικής προς κινητά</translation>
<translation id="59107663811261420">Αυτός ο τύπος κάρτας δεν υποστηρίζεται από το Google Payments γι' αυτόν τον έμπορο. Επιλέξτε διαφορετική κάρτα.</translation>
+<translation id="5975083100439434680">Σμίκρυνση</translation>
<translation id="5989320800837274978">Δεν προσδιορίζονται ούτε οι σταθεροί διακομιστές μεσολάβησης ούτε μια διεύθυνση URL σεναρίου .pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Κλείσιμο</translation>
+<translation id="6060685159320643512">Προσοχή, τέτοια πειράματα είναι επικύνδυνα</translation>
+<translation id="6151417162996330722">Το πιστοποιητικό του διακομιστή έχει πολύ μεγάλη περίοδο εγκυρότητας.</translation>
<translation id="6154808779448689242">Το εμφανιζόμενο διακριτικό πολιτικής δεν αντιστοιχεί με το τρέχον διακριτικό</translation>
<translation id="6165508094623778733">Μάθετε περισσότερα</translation>
<translation id="6259156558325130047">&amp;Επανάληψη αναδιάταξης</translation>
-<translation id="6263376278284652872">Σελιδοδείκτες <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Σελιδοδείκτες <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Ταχυδρομικός κώδικας</translation>
<translation id="6337534724793800597">Φιλτράρισμα πολιτικών με βάση το όνομα</translation>
+<translation id="6387478394221739770">Θέλετε να ενημερώνεστε για τις συναρπαστικές νέες δυνατότητες του Chrome; Επισκεφτείτε το κανάλι beta στη διεύθυνση chrome.com/beta.</translation>
+<translation id="6426993025560594914">Όλα τα πειράματα είναι διαθέσιμα στην πλατφόρμα σας!</translation>
<translation id="6445051938772793705">Χώρα</translation>
<translation id="6458467102616083041">Αγνοήθηκε επειδή η προεπιλεγμένη αναζήτηση είναι απενεργοποιημένη από την πολιτική.</translation>
<translation id="647261751007945333">Πολιτικές συσκευών </translation>
<translation id="6512448926095770873">Έξοδος από αυτή τη σελίδα</translation>
<translation id="6529602333819889595">&amp;Επανάληψη διαγραφής</translation>
<translation id="6550675742724504774">Επιλογές</translation>
-<translation id="6597614308054261376">Προσπαθείτε να φτάσετε στο <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Προς το παρόν δεν είναι δυνατή η μεσολάβηση αυτής της σελίδας από την Εξοικονόμηση δεδομένων.</translation>
-<translation id="6628463337424475685">Αναζήτηση <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Προσπαθείτε να φτάσετε στο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Προς το παρόν δεν είναι δυνατή η μεσολάβηση αυτής της σελίδας από την Εξοικονόμηση δεδομένων.</translation>
+<translation id="6628463337424475685">Αναζήτηση <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Αυτή η πολιτική έχει αποσυρθεί.</translation>
<translation id="6646897916597483132">Εισαγάγετε τον τετραψήφιο κωδικό CVC από το μπροστινό μέρος της κάρτας σας</translation>
+<translation id="674375294223700098">Άγνωστο σφάλμα πιστοποιητικού διακομιστή</translation>
<translation id="6753269504797312559">Τιμή πολιτικής</translation>
<translation id="6831043979455480757">Μετάφραση</translation>
<translation id="6839929833149231406">Περιοχή</translation>
<translation id="6874604403660855544">&amp;Επανάληψη προσθήκης</translation>
<translation id="6891596781022320156">Το επίπεδο πολιτικής δεν υποστηρίζεται.</translation>
<translation id="6915804003454593391">Χρήστης</translation>
+<translation id="6957887021205513506">Το πιστοποιητικό του διακομιστή φαίνεται να είναι πλαστό.</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6965978654500191972">Συσκευή</translation>
<translation id="6970216967273061347">Περιοχή</translation>
<translation id="6973656660372572881">Καθορίζονται τόσο οι σταθεροί διακομιστές μεσολάβησης όσο και μια διεύθυνση URL σεναρίου .pac.</translation>
<translation id="6980028882292583085">Ειδοποίηση JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Επιχειρήσατε να μεταβείτε στο <ph name="DOMAIN" />, αλλά ο διακομιστής παρουσίασε ένα πιστοποιητικό με περίοδο εγκυρότητας η οποία είναι πολύ μεγάλη για να θεωρηθεί αξιόπιστη.</translation>
<translation id="7087282848513945231">Περιφέρεια</translation>
-<translation id="7108649287766967076">Η μετάφραση στα <ph name="TARGET_LANGUAGE"/> απέτυχε.</translation>
+<translation id="7108649287766967076">Η μετάφραση στα <ph name="TARGET_LANGUAGE" /> απέτυχε.</translation>
<translation id="7139724024395191329">Εμιράτο</translation>
+<translation id="7179921470347911571">Επανεκκίνηση τώρα</translation>
<translation id="7180611975245234373">Ανανέωση</translation>
<translation id="7182878459783632708">Δεν έχουν οριστεί πολιτικές</translation>
-<translation id="7186367841673660872">Αυτή η σελίδα έχει μεταφραστεί από τα<ph name="ORIGINAL_LANGUAGE"/>στα<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="7186367841673660872">Αυτή η σελίδα έχει μεταφραστεί από τα<ph name="ORIGINAL_LANGUAGE" />στα<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Αναζήτηση <ph name="SITE_NAME"/> για <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Αναζήτηση <ph name="SITE_NAME" /> για <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Δεν είναι δυνατή η επίτευξη ιδιωτικής σύνδεσης με τον τομέα <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> επειδή η ημερομηνία και η ώρα (<ph name="DATE_AND_TIME" />) του υπολογιστή σας είναι λανθασμένες.</translation>
<translation id="7275334191706090484">Διαχειριζόμενοι σελιδοδείκτες</translation>
<translation id="7298195798382681320">Προτεινόμενες</translation>
<translation id="7334320624316649418">&amp;Επανάληψη αναδιάταξης</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Υποχρεωτική</translation>
<translation id="7542995811387359312">Η αυτόματη συμπλήρωση πιστωτικής κάρτας έχει απενεργοποιηθεί, επειδή αυτή η φόρμα δεν χρησιμοποιεί ασφαλή σύνδεση.</translation>
-<translation id="7568593326407688803">Αυτή η σελίδα είναι στα<ph name="ORIGINAL_LANGUAGE"/>Θέλετε να τη μεταφράσετε;</translation>
+<translation id="7567204685887185387">Ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του μπορεί να εκδόθηκε παράνομα. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
+<translation id="7568593326407688803">Αυτή η σελίδα είναι στα<ph name="ORIGINAL_LANGUAGE" />Θέλετε να τη μεταφράσετε;</translation>
<translation id="7569952961197462199">Κατάργηση πιστωτικής κάρτας από το Chrome;</translation>
-<translation id="7600965453749440009">Να μην γίνεται ποτέ μετάφραση από <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Η τιμή είναι εκτός του εύρους τιμών <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Το πιστοποιητικό του διακομιστή παραβαίνει τους περιορισμούς ονόματος.</translation>
+<translation id="7600965453749440009">Να μην γίνεται ποτέ μετάφραση από <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Η τιμή είναι εκτός του εύρους τιμών <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Θέλετε να ενημερώνεστε για τις συναρπαστικές νέες δυνατότητες του Chrome; Επισκεφτείτε το κανάλι προγραμματιστών στη διεύθυνση chrome.com/dev.</translation>
<translation id="7752995774971033316">Χωρίς διαχείριση</translation>
+<translation id="7761701407923456692">Το πιστοποιητικό του διακομιστή δεν συμφωνεί με τη διεύθυνση URL.</translation>
<translation id="777702478322588152">Νομαρχία</translation>
<translation id="7791543448312431591">Προσθήκη</translation>
<translation id="7805768142964895445">Κατάσταση</translation>
<translation id="7813600968533626083">Κατάργηση πρότασης φόρμας από το Chrome;</translation>
<translation id="7887683347370398519">Ελέγξτε τον κωδικό σας CVC και δοκιμάστε ξανά</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Το πιστοποιητικό του διακομιστή δεν είναι ακόμα έγκυρο.</translation>
<translation id="7956713633345437162">Σελιδοδείκτες κινητής συσκευής</translation>
<translation id="7961015016161918242">Ποτέ</translation>
<translation id="7977590112176369853">&lt;πληκτρολογήστε ερώτημα&gt;</translation>
-<translation id="7983301409776629893">Να γίνεται πάντα μετάφραση των <ph name="ORIGINAL_LANGUAGE"/> στα <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Να γίνεται πάντα μετάφραση των <ph name="ORIGINAL_LANGUAGE" /> στα <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Σελιδοδείκτες επιτραπέζιου υπολογιστή</translation>
<translation id="7995512525968007366">Δεν καθορίστηκε</translation>
-<translation id="8034522405403831421">Αυτή η σελίδα είναι στα <ph name="SOURCE_LANGUAGE"/>. Μετάφρασή της στα <ph name="TARGET_LANGUAGE"/>;</translation>
+<translation id="8003882219468422867">Παράκαμψη επιχείρησης</translation>
+<translation id="8034522405403831421">Αυτή η σελίδα είναι στα <ph name="SOURCE_LANGUAGE" />. Μετάφρασή της στα <ph name="TARGET_LANGUAGE" />;</translation>
<translation id="8088680233425245692">Αποτυχία προβολής άρθρου.</translation>
<translation id="8091372947890762290">Η ενεργοποίηση στο διακομιστή εκκρεμεί</translation>
<translation id="8194797478851900357">&amp;Αναίρεση μετακίνησης</translation>
-<translation id="8201077131113104583">Η διεύθυνση URL ενημέρωσης για την επέκταση με αναγνωριστικό ID &quot;<ph name="EXTENSION_ID"/>&quot;, δεν είναι έγκυρη.</translation>
+<translation id="8201077131113104583">Η διεύθυνση URL ενημέρωσης για την επέκταση με αναγνωριστικό ID "<ph name="EXTENSION_ID" />", δεν είναι έγκυρη.</translation>
<translation id="8208216423136871611">Να μην γίνει αποθήκευση</translation>
<translation id="8218327578424803826">Εκχωρημένη τοποθεσία:</translation>
<translation id="8249320324621329438">Τελευταία ανάκτηση:</translation>
+<translation id="8294431847097064396">Πηγή</translation>
<translation id="8308427013383895095">Η μετάφραση απέτυχε λόγω προβλήματος με τη σύνδεση δικτύου.</translation>
<translation id="8311778656528046050">Είστε βέβαιοι ότι επιθυμείτε να φορτώσετε ξανά αυτήν τη σελίδα;</translation>
<translation id="8349305172487531364">Γραμμή σελιδοδεικτών</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Ισχύει για</translation>
<translation id="8530504477309582336">Αυτός ο τύπος κάρτας δεν υποστηρίζεται από το Google Payments. Επιλέξτε άλλη κάρτα.</translation>
<translation id="8553075262323480129">Η μετάφραση απέτυχε επειδή δεν ήταν δυνατός ο προσδιορισμός της σελίδας.</translation>
-<translation id="8571890674111243710">Μετάφραση σελίδας σε <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Δεν είναι δυνατή η επίτευξη ιδιωτικής σύνδεσης με τον τομέα <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> επειδή η ημερομηνία και η ώρα (<ph name="DATE_AND_TIME" />) της συσκευής σας είναι λανθασμένες.</translation>
+<translation id="8571890674111243710">Μετάφραση σελίδας σε <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Επαναφορά προεπιλογών</translation>
<translation id="8713130696108419660">Εσφαλμένη αρχική υπογραφή</translation>
<translation id="8725066075913043281">Προσπαθήστε ξανά</translation>
+<translation id="8738058698779197622">Για την επίτευξη μιας ασφαλούς σύνδεσης, θα πρέπει να γίνει σωστή ρύθμιση του ρολογιού σας. Αυτό οφείλεται στο γεγονός ότι τα πιστοποιητικά που χρησιμοποιούν οι ιστότοποι για την ταυτοποίησή τους είναι έγκυρα μόνο για συγκεκριμένες χρονικές περιόδους. Εφόσον το ρολόι της συσκευής σας δεν είναι σωστά ρυθμισμένο, το Chromium δεν μπορεί να επαληθεύσει αυτά τα πιστοποιητικά.</translation>
<translation id="8790007591277257123">&amp;Επανάληψη διαγραφής</translation>
<translation id="8804164990146287819">Πολιτική Απορρήτου</translation>
+<translation id="8820817407110198400">Σελιδοδείκτες</translation>
<translation id="8824019021993735287">Δεν ήταν δυνατή η επαλήθευση της κάρτας σας αυτήν τη στιγμή από το Chrome. Δοκιμάστε ξανά αργότερα.</translation>
<translation id="8834246243508017242">Ενεργοποίηση Αυτόματης συμπλήρωσης χρησιμοποιώντας τις Επαφές…</translation>
<translation id="883848425547221593">Άλλοι σελιδοδείκτες</translation>
+<translation id="884923133447025588">Δεν εντοπίστηκε μηχανισμός ακύρωσης.</translation>
<translation id="8866481888320382733">Σφάλμα ανάλυσης ρυθμίσεων πολιτικής</translation>
<translation id="8876793034577346603">Αποτυχία ανάλυσης της διαμόρφωσης δικτύου</translation>
<translation id="8891727572606052622">Μη έγκυρη λειτουργία διακομιστή μεσολάβησης.</translation>
-<translation id="8940229512486821554">Εκτέλεση εντολής <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Λυπούμαστε, αυτό το πείραμα δεν είναι διαθέσιμο στην πλατφόρμα σας.</translation>
+<translation id="8903921497873541725">Μεγέθυνση</translation>
+<translation id="8932102934695377596">Το ρολόι σας πάει πίσω</translation>
+<translation id="8940229512486821554">Εκτέλεση εντολής <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Το πιστοποιητικό του διακομιστή έχει λήξει.</translation>
<translation id="8988760548304185580">Εισαγάγετε την ημερομηνία λήξης και τον τριψήφιο κωδικό CVC από το πίσω μέρος της κάρτας σας</translation>
-<translation id="9020542370529661692">Αυτή η σελίδα έχει μεταφραστεί στα <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="901974403500617787">Οι επισημάνσεις που ισχύουν για ολόκληρο το σύστημα μπορούν να οριστούν μόνο από τον κάτοχο: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Αυτή η σελίδα έχει μεταφραστεί στα <ph name="TARGET_LANGUAGE" />.</translation>
+<translation id="9049981332609050619">Επιχειρήσατε να μεταβείτε στον <ph name="DOMAIN" /> , αλλά ο διακομιστής παρουσίασε ένα μη έγκυρο πιστοποιητικό.</translation>
<translation id="9125941078353557812">Εισαγάγετε τον τριψήφιο κωδικό CVC από το πίσω μέρος της κάρτας σας</translation>
<translation id="9137013805542155359">Εμφάνιση πρωτοτύπου</translation>
<translation id="9148507642005240123">&amp;Αναίρεση επεξεργασίας</translation>
<translation id="9154176715500758432">Παραμονή σε αυτή τη σελίδα</translation>
<translation id="9170848237812810038">Αναί&amp;ρεση</translation>
+<translation id="917450738466192189">Το πιστοποιητικό του διακομιστή δεν είναι έγκυρο.</translation>
+<translation id="9187827965378254003">Δυστυχώς, φαίνεται πως δεν υπάρχουν διαθέσιμα πειράματα αυτή τη στιγμή.</translation>
<translation id="9207861905230894330">Αποτυχία προσθήκης άρθρου.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ΔΙΑΓΡΑΦΗ ΦΟΡΜΑΣ</translation>
+<translation id="988159990683914416">Έκδοση προγραμματιστή</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_en-GB.xtb b/chromium/components/strings/components_strings_en-GB.xtb
index e9b5755468d..37c419333d0 100644
--- a/chromium/components/strings/components_strings_en-GB.xtb
+++ b/chromium/components/strings/components_strings_en-GB.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="en-GB">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="en-GB">
+<translation id="1032854598605920125">Rotate clockwise</translation>
<translation id="1055184225775184556">&amp;Undo Add</translation>
<translation id="106701514854093668">Desktop Bookmarks</translation>
-<translation id="1103523840287552314">Always translate <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Fit to width</translation>
+<translation id="1103523840287552314">Always translate <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Undo reorder</translation>
<translation id="111844081046043029">Are you sure that you want to leave this page?</translation>
<translation id="112840717907525620">Policy cache OK</translation>
<translation id="1132774398110320017">Chrome Auto-fill settings...</translation>
-<translation id="1152921474424827756">Access a <ph name="BEGIN_LINK"/>cached copy<ph name="END_LINK"/> of <ph name="URL"/></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="1152921474424827756">Access a <ph name="BEGIN_LINK" />cached copy<ph name="END_LINK" /> of <ph name="URL" /></translation>
+<translation id="121201262018556460">You attempted to reach <ph name="DOMAIN" />, but the server presented a certificate containing a weak key. An attacker could have broken the private key and the server may not be the server you expected (you may be communicating with an attacker).</translation>
<translation id="1227224963052638717">Unknown policy.</translation>
<translation id="1227633850867390598">Hide value</translation>
<translation id="1228893227497259893">Wrong entity identifier</translation>
@@ -14,65 +20,78 @@
<translation id="1339601241726513588">Enrolment domain:</translation>
<translation id="1344588688991793829">Chromium Auto-fill settings...</translation>
<translation id="1426410128494586442">Yes</translation>
+<translation id="1430915738399379752">Print</translation>
<translation id="1455235771979731432">There was a problem verifying your card. Check your Internet connection and try again.</translation>
<translation id="1491151370853475546">Reload this Page</translation>
<translation id="1549470594296187301">JavaScript must be enabled to use this feature.</translation>
-<translation id="1639239467298939599">Loading</translation>
<translation id="1640180200866533862">User policies</translation>
<translation id="1644184664548287040">The network configuration is invalid and couldn't be imported.</translation>
-<translation id="1693754753824026215">The page at <ph name="SITE"/> says:</translation>
+<translation id="1655462015569774233">{1,plural, =1{This server could not prove that it is <ph name="DOMAIN" />; its security certificate expired yesterday. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE" />. Does that look right? If not, you should correct your system's clock and then refresh this page.}other{This server could not prove that it is <ph name="DOMAIN" />; its security certificate expired # days ago. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE" />. Does that look right? If not, you should correct your system's clock and then refresh this page.}}</translation>
+<translation id="168841957122794586">The server certificate contains a weak cryptographic key.</translation>
+<translation id="1693754753824026215">The page at <ph name="SITE" /> says:</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="1734864079702812349">Amex</translation>
+<translation id="1753706481035618306">Page number</translation>
+<translation id="1763864636252898013">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by your device's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
<translation id="1821930232296380041">Invalid request or request parameters</translation>
-<translation id="1853748787962613237">Failed to display article.</translation>
<translation id="1871208020102129563">Proxy is set to use fixed proxy servers, not a .pac script URL.</translation>
-<translation id="1875753206475436906">heuristic type: <ph name="HEURISTIC_TYPE"/>
- server type: <ph name="SERVER_TYPE"/>
- field signature: <ph name="FIELD_SIGNATURE"/>
- form signature: <ph name="FORM_SIGNATURE"/>
- experiment id: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Go to <ph name="LINK"/></translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> Bookmarks</translation>
+<translation id="194030505837763158">Go to <ph name="LINK" /></translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> Bookmarks</translation>
<translation id="1973335181906896915">Serialisation error</translation>
+<translation id="1974060860693918893">Advanced</translation>
<translation id="2025186561304664664">Proxy is set to auto-configured.</translation>
<translation id="2025623846716345241">Confirm Reload</translation>
-<translation id="2030481566774242610">Did you mean <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Did you mean <ph name="LINK" />?</translation>
<translation id="2053553514270667976">ZIP code</translation>
<translation id="20817612488360358">System proxy settings are set to be used but an explicit proxy configuration is also specified.</translation>
<translation id="2094505752054353250">Domain mismatch</translation>
<translation id="2096368010154057602">Department</translation>
<translation id="2113977810652731515">Card</translation>
-<translation id="2114841414352855701">Ignored because it was overridden by <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Ignored because it was overridden by <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Mobile Bookmarks</translation>
+<translation id="2171101176734966184">You attempted to reach <ph name="DOMAIN" />, but the server presented a certificate signed using a weak signature algorithm. This means that the security credentials the server presented could have been forged and the server may not be the server you expected (you may be communicating with an attacker).</translation>
<translation id="2181821976797666341">Policies</translation>
<translation id="2212735316055980242">Policy not found</translation>
<translation id="2213606439339815911">Fetching entries...</translation>
<translation id="225207911366869382">This value is deprecated for this policy.</translation>
<translation id="2262243747453050782">HTTP error</translation>
-<translation id="2270192940992995399">Failed to find article.</translation>
-<translation id="2328300916057834155">Ignored invalid bookmark at index <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Unavailable Experiments</translation>
+<translation id="229702904922032456">A root or intermediate certificate has expired.</translation>
+<translation id="2328300916057834155">Ignored invalid bookmark at index <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Other bookmarks</translation>
<translation id="2359808026110333948">Continue</translation>
<translation id="2367567093518048410">Level</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="2396249848217231973">&amp;Undo delete</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="2455981314101692989">This web page has disabled automatic filling for this form.</translation>
<translation id="2479410451996844060">Invalid search URL.</translation>
+<translation id="2491120439723279231">Server's certificate contains errors.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2498091847651709837">Scan new card</translation>
<translation id="2556876185419854533">&amp;Undo Edit</translation>
-<translation id="2581221116934462656">Would you like <ph name="PRODUCT_NAME"/> to offer to translate <ph name="LANGUAGE_NAME"/> pages from this site next time?</translation>
+<translation id="2581221116934462656">Would you like <ph name="PRODUCT_NAME" /> to offer to translate <ph name="LANGUAGE_NAME" /> pages from this site next time?</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">This document is password-protected. Please enter a password.</translation>
+<translation id="2625385379895617796">Your clock is ahead</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2653659639078652383">Submit</translation>
<translation id="2704283930420550640">Value doesn't match format.</translation>
<translation id="2721148159707890343">Request succeeded</translation>
+<translation id="2728127805433021124">Server's certificate is signed using a weak signature algorithm.</translation>
<translation id="2774256287122201187">You may continue. If you continue to the page, this warning will not appear again for five minutes.</translation>
<translation id="277499241957683684">Missing device record</translation>
<translation id="2835170189407361413">Clear form</translation>
-<translation id="2855922900409897335">Verify your <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Verify your <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">This server could not prove that it is <ph name="DOMAIN" />; its security certificate expired. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_TIME" />. Does that look right? If not, you should correct your system's clock and then refresh this page.</translation>
+<translation id="2922350208395188000">Server's certificate cannot be checked.</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="2958431318199492670">The network configuration doesn't comply to the ONC standard. Parts of the configuration may not be imported.</translation>
<translation id="2972581237482394796">&amp;Redo</translation>
-<translation id="3010559122411665027">List entry &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">List entry "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Wrong policy type</translation>
<translation id="3105172416063519923">Asset ID:</translation>
<translation id="3145945101586104090">Failed to decode response</translation>
@@ -80,32 +99,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Island</translation>
<translation id="3219579145727097045">Enter the expiration date and 4-digit CVC from the front of your card</translation>
-<translation id="3228969707346345236">The translation failed because the page is already in <ph name="LANGUAGE"/>.</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="3228969707346345236">The translation failed because the page is already in <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Undo Reorder</translation>
+<translation id="3286538390144397061">Restart Now</translation>
<translation id="333371639341676808">Prevent this page from creating additional dialogues.</translation>
-<translation id="3369366829301677151">Update and verify your <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">settings</translation>
+<translation id="3369192424181595722">Clock error</translation>
+<translation id="3369366829301677151">Update and verify your <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Deprovisioned</translation>
<translation id="3377188786107721145">Policy parse error</translation>
<translation id="3380365263193509176">Unknown error</translation>
<translation id="3380864720620200369">Client ID:</translation>
<translation id="3427342743765426898">&amp;Redo Edit</translation>
+<translation id="3435896845095436175">Enable</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Fetch interval:</translation>
+<translation id="3462200631372590220">Hide advanced</translation>
+<translation id="3528171143076753409">Server's certificate is not trusted</translation>
<translation id="3542684924769048008">Use password for:</translation>
<translation id="3583757800736429874">&amp;Redo Move</translation>
<translation id="3623476034248543066">Show value</translation>
+<translation id="3648607100222897006">These experimental features may change, break or disappear at any time. We make absolutely no guarantees about what may happen if you turn one of these experiments on, and your browser may even spontaneously combust. Jokes aside, your browser may delete all your data or your security and privacy could be compromised in unexpected ways. Any experiments that you enable will be enabled for all users of this browser. Please proceed with caution.</translation>
<translation id="3650584904733503804">Validation successful</translation>
<translation id="370665806235115550">Loading...</translation>
<translation id="3712624925041724820">Licenses exhausted</translation>
<translation id="3739623965217189342">Link that you copied</translation>
<translation id="375403751935624634">The translation failed because of a server error.</translation>
<translation id="385051799172605136">Back</translation>
+<translation id="3858027520442213535">Update date and time</translation>
<translation id="3884278016824448484">Conflicting device identifier</translation>
<translation id="3885155851504623709">Parish</translation>
<translation id="3934680773876859118">Failed to load PDF document</translation>
<translation id="3963721102035795474">Reader Mode</translation>
<translation id="4030383055268325496">&amp;Undo add</translation>
-<translation id="4058922952496707368">Key &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">WARNING</translation>
+<translation id="4058922952496707368">Key "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Proxy configuration is set to use a .pac script URL, not fixed proxy servers.</translation>
<translation id="409504436206021213">Don't Reload</translation>
<translation id="4103249731201008433">Device serial number is invalid</translation>
@@ -118,40 +147,56 @@
<translation id="4258748452823770588">Bad signature</translation>
<translation id="4269787794583293679">(No username)</translation>
<translation id="4300246636397505754">Parent suggestions</translation>
-<translation id="4372948949327679948">Expected <ph name="VALUE_TYPE"/> value.</translation>
+<translation id="4325863107915753736">Failed to find article</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="4394049700291259645">Disable</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="443673843213245140">Use of a proxy is disabled but an explicit proxy configuration is specified.</translation>
-<translation id="4506176782989081258">Validation error: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Validation error: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Remove address from Chrome?</translation>
<translation id="4594403342090139922">&amp;Undo Delete</translation>
<translation id="4607653538520819196">This page cannot be proxied by Data Saver.</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="4726672564094551039">Reload policies</translation>
+<translation id="4728558894243024398">Platform</translation>
+<translation id="4771973620359291008">An unknown error has occurred.</translation>
<translation id="4800132727771399293">Check your expiration date and CVC and try again</translation>
<translation id="4813512666221746211">Network error</translation>
+<translation id="4816492930507672669">Fit to page</translation>
<translation id="4850886885716139402">View</translation>
-<translation id="4923417429809017348">This page has been translated from an unknown language into <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">This page has been translated from an unknown language into <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Must be specified.</translation>
<translation id="4968547170521245791">Cannot Proxy</translation>
-<translation id="498957508165411911">Translate from <ph name="ORIGINAL_LANGUAGE"/> to <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Translate from <ph name="ORIGINAL_LANGUAGE" /> to <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Backing store in bad state</translation>
<translation id="5031870354684148875">About Google Translate</translation>
+<translation id="5045550434625856497">Incorrect password</translation>
+<translation id="5087286274860437796">Server's certificate is not valid at this time.</translation>
<translation id="5089810972385038852">County</translation>
+<translation id="5094747076828555589">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by Chromium. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
<translation id="5095208057601539847">Province</translation>
<translation id="5145883236150621069">Error code present in the policy response</translation>
<translation id="5172758083709347301">Machine</translation>
-<translation id="5179510805599951267">Not in <ph name="ORIGINAL_LANGUAGE"/>? Report this error</translation>
+<translation id="5179510805599951267">Not in <ph name="ORIGINAL_LANGUAGE" />? Report this error</translation>
<translation id="5190835502935405962">Bookmarks Bar</translation>
+<translation id="5199729219167945352">Experiments</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">Confirm Navigation</translation>
<translation id="5299298092464848405">Error parsing policy</translation>
+<translation id="5316812925700871227">Rotate Anti-clockwise</translation>
<translation id="5317780077021120954">Save</translation>
<translation id="536296301121032821">Failed to store policy settings</translation>
-<translation id="5439770059721715174">Schema validation error at &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Schema validation error at "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Bad policy timestamp</translation>
<translation id="5470861586879999274">&amp;Redo edit</translation>
<translation id="5509780412636533143">Managed bookmarks</translation>
<translation id="5523118979700054094">Policy name</translation>
<translation id="552553974213252141">Was the text extracted correctly?</translation>
<translation id="5540224163453853">Could not find the requested article.</translation>
+<translation id="5556459405103347317">Reload</translation>
<translation id="5565735124758917034">Active</translation>
<translation id="560412284261940334">Management not supported</translation>
<translation id="5629630648637658800">Failed to load policy settings</translation>
@@ -159,46 +204,56 @@
<translation id="5720705177508910913">Current user</translation>
<translation id="5813119285467412249">&amp;Redo Add</translation>
<translation id="5872918882028971132">Parent Suggestions</translation>
-<translation id="587701087903783706">Close mobile-friendly view</translation>
<translation id="59107663811261420">This type of card is not supported by Google Payments for this merchant. Please select a different card.</translation>
+<translation id="5975083100439434680">Zoom out</translation>
<translation id="5989320800837274978">Neither fixed proxy servers nor a .pac script URL are specified.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Close</translation>
+<translation id="6060685159320643512">Careful, these experiments may bite</translation>
+<translation id="6151417162996330722">The server certificate has a validity period that is too long.</translation>
<translation id="6154808779448689242">Returned policy token doesn't match current token</translation>
<translation id="6165508094623778733">Learn more</translation>
<translation id="6259156558325130047">&amp;Redo Reorder</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> bookmarks</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> bookmarks</translation>
<translation id="6282194474023008486">Postcode</translation>
<translation id="6337534724793800597">Filter policies by name</translation>
+<translation id="6387478394221739770">Interested in cool new Chrome features? Try our beta channel at chrome.com/beta.</translation>
+<translation id="6426993025560594914">All experiments are available on your platform!</translation>
<translation id="6445051938772793705">Country</translation>
<translation id="6458467102616083041">Ignored because default search is disabled by policy.</translation>
<translation id="647261751007945333">Device policies</translation>
<translation id="6512448926095770873">Leave this Page</translation>
<translation id="6529602333819889595">&amp;Redo Delete</translation>
<translation id="6550675742724504774">Options</translation>
-<translation id="6597614308054261376">You are trying to reach <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. This page cannot be proxied by Data Saver at this time.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Search</translation>
+<translation id="6597614308054261376">You are trying to reach <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. This page cannot be proxied by Data Saver at this time.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Search</translation>
<translation id="6644283850729428850">This policy has been deprecated.</translation>
<translation id="6646897916597483132">Enter the 4-digit CVC from the front of your card</translation>
+<translation id="674375294223700098">Unknown server certificate error.</translation>
<translation id="6753269504797312559">Policy Value</translation>
<translation id="6831043979455480757">Translate</translation>
<translation id="6839929833149231406">Area</translation>
<translation id="6874604403660855544">&amp;Redo add</translation>
<translation id="6891596781022320156">Policy level is not supported.</translation>
<translation id="6915804003454593391">User:</translation>
+<translation id="6957887021205513506">The server's certificate appears to be a forgery.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">JavaScript Alert</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">You attempted to reach <ph name="DOMAIN" />, but the server presented a certificate whose validity period is too long to be trustworthy.</translation>
<translation id="7087282848513945231">County</translation>
-<translation id="7108649287766967076">The translation to <ph name="TARGET_LANGUAGE"/> failed.</translation>
+<translation id="7108649287766967076">The translation to <ph name="TARGET_LANGUAGE" /> failed.</translation>
<translation id="7139724024395191329">Emirate</translation>
+<translation id="7179921470347911571">Relaunch Now</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="7186367841673660872">This page has been translated from<ph name="ORIGINAL_LANGUAGE" />to<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Search <ph name="SITE_NAME"/> for <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Search <ph name="SITE_NAME" /> for <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">A private connection to <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> can't be established because your computer's date and time (<ph name="DATE_AND_TIME" />) are incorrect.</translation>
<translation id="7275334191706090484">Managed Bookmarks</translation>
<translation id="7298195798382681320">Recommended</translation>
<translation id="7334320624316649418">&amp;Redo reorder</translation>
@@ -209,31 +264,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Mandatory</translation>
<translation id="7542995811387359312">Automatic credit card filling is disabled because this form does not use a secure connection.</translation>
-<translation id="7568593326407688803">This page is in<ph name="ORIGINAL_LANGUAGE"/>Would you like to translate it?</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="7568593326407688803">This page is in<ph name="ORIGINAL_LANGUAGE" />Would you like to translate it?</translation>
<translation id="7569952961197462199">Remove credit card from Chrome?</translation>
-<translation id="7600965453749440009">Never translate <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Value is out of range <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Server's certificate violates name constraints.</translation>
+<translation id="7600965453749440009">Never translate <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Value is out of range <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Interested in cool new Chrome features? Try our dev channel at chrome.com/dev.</translation>
<translation id="7752995774971033316">Unmanaged</translation>
+<translation id="7761701407923456692">Server's certificate does not match the URL.</translation>
<translation id="777702478322588152">Prefecture</translation>
<translation id="7791543448312431591">Add</translation>
<translation id="7805768142964895445">Status</translation>
<translation id="7813600968533626083">Remove form suggestion from Chrome?</translation>
<translation id="7887683347370398519">Check your CVC and try again</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Server's certificate is not yet valid.</translation>
<translation id="7956713633345437162">Mobile bookmarks</translation>
<translation id="7961015016161918242">Never</translation>
<translation id="7977590112176369853">&lt;enter query&gt;</translation>
-<translation id="7983301409776629893">Always translate <ph name="ORIGINAL_LANGUAGE"/> to <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Always translate <ph name="ORIGINAL_LANGUAGE" /> to <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Desktop bookmarks</translation>
<translation id="7995512525968007366">Not Specified</translation>
-<translation id="8034522405403831421">This page is in <ph name="SOURCE_LANGUAGE"/>. Translate it to <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Enterprise override</translation>
+<translation id="8034522405403831421">This page is in <ph name="SOURCE_LANGUAGE" />. Translate it to <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Failed to view article.</translation>
<translation id="8091372947890762290">Activation is pending on the server</translation>
<translation id="8194797478851900357">&amp;Undo Move</translation>
-<translation id="8201077131113104583">Invalid update URL for extension with ID &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">Invalid update URL for extension with ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Don't save</translation>
<translation id="8218327578424803826">Assigned Location:</translation>
<translation id="8249320324621329438">Last fetched:</translation>
+<translation id="8294431847097064396">Source</translation>
<translation id="8308427013383895095">The translation failed because of a problem with the network connection.</translation>
<translation id="8311778656528046050">Are you sure you want to reload this page?</translation>
<translation id="8349305172487531364">Bookmarks bar</translation>
@@ -242,25 +304,40 @@
<translation id="8488350697529856933">Applies to</translation>
<translation id="8530504477309582336">This type of card is not supported by Google Payments. Please select a different card.</translation>
<translation id="8553075262323480129">The translation failed because the page's language could not be determined.</translation>
-<translation id="8571890674111243710">Translating page into <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">A private connection to <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> can't be established because your device's date and time (<ph name="DATE_AND_TIME" />) are incorrect.</translation>
+<translation id="8571890674111243710">Translating page into <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Reset all to default</translation>
<translation id="8713130696108419660">Bad intial signature</translation>
<translation id="8725066075913043281">Try again</translation>
+<translation id="8738058698779197622">To establish a secure connection, your clock needs to be set correctly. This is because the certificates that websites use to identify themselves are only valid for specific periods of time. Since your device's clock is incorrect, Chromium cannot verify these certificates.</translation>
<translation id="8790007591277257123">&amp;Redo delete</translation>
<translation id="8804164990146287819">Privacy Policy</translation>
+<translation id="8820817407110198400">Bookmarks</translation>
<translation id="8824019021993735287">Chrome was unable to verify your card at this time. Please try again later.</translation>
<translation id="8834246243508017242">Enable Autofill using Contacts…</translation>
<translation id="883848425547221593">Other Bookmarks</translation>
+<translation id="884923133447025588">No revocation mechanism found.</translation>
<translation id="8866481888320382733">Error parsing policy settings</translation>
<translation id="8876793034577346603">Network configuration failed to be parsed.</translation>
<translation id="8891727572606052622">Invalid proxy mode.</translation>
-<translation id="8940229512486821554">Run <ph name="EXTENSION_NAME"/> command: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Sorry, this experiment is not available on your platform.</translation>
+<translation id="8903921497873541725">Zoom in</translation>
+<translation id="8932102934695377596">Your clock is behind</translation>
+<translation id="8940229512486821554">Run <ph name="EXTENSION_NAME" /> command: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Server's certificate has expired.</translation>
<translation id="8988760548304185580">Enter the expiry date and 3-digit CVC from the back of your card</translation>
-<translation id="9020542370529661692">This page has been translated to <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Flags that apply system-wide can only be set by the owner: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">This page has been translated to <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">You attempted to reach <ph name="DOMAIN" />, but the server presented an invalid certificate.</translation>
<translation id="9125941078353557812">Enter the 3-digit CVC from the back of your card</translation>
<translation id="9137013805542155359">Show original</translation>
<translation id="9148507642005240123">&amp;Undo edit</translation>
<translation id="9154176715500758432">Stay on this Page</translation>
<translation id="9170848237812810038">&amp;Undo</translation>
+<translation id="917450738466192189">Server's certificate is invalid.</translation>
+<translation id="9187827965378254003">Oh dear, it looks like there are currently no experiments available.</translation>
<translation id="9207861905230894330">Failed to add article.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">CLEAR FORM</translation>
+<translation id="988159990683914416">Developer Build</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_es-419.xtb b/chromium/components/strings/components_strings_es-419.xtb
index 4cb49e908cf..53e07ba595a 100644
--- a/chromium/components/strings/components_strings_es-419.xtb
+++ b/chromium/components/strings/components_strings_es-419.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="es-419">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="es-419">
+<translation id="1032854598605920125">Girar a la derecha</translation>
<translation id="1055184225775184556">&amp;Deshacer Agregar</translation>
<translation id="106701514854093668">Marcadores de escritorio</translation>
-<translation id="1103523840287552314">Siempre traducir <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Ajustar al ancho</translation>
+<translation id="1103523840287552314">Siempre traducir <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Deshacer Reorganizar</translation>
<translation id="111844081046043029">¿Estás seguro de que deseas abandonar esta página?</translation>
<translation id="112840717907525620">Caché de política correcta</translation>
<translation id="1132774398110320017">Configuración de la función Autocompletar de Chrome…</translation>
-<translation id="1152921474424827756">Accede a una <ph name="BEGIN_LINK"/>copia almacenada en caché<ph name="END_LINK"/> de <ph name="URL"/>.</translation>
+<translation id="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="1152921474424827756">Accede a una <ph name="BEGIN_LINK" />copia almacenada en caché<ph name="END_LINK" /> de <ph name="URL" />.</translation>
+<translation id="121201262018556460">Intentaste acceder a <ph name="DOMAIN" />, pero el servidor presentó un certificado que contiene una clave no segura. Es posible que un atacante haya descifrado la clave privada y que este no sea el servidor esperado (es posible que hayas establecido comunicación con un atacante).</translation>
<translation id="1227224963052638717">Política desconocida</translation>
<translation id="1227633850867390598">Ocultar valor</translation>
<translation id="1228893227497259893">El identificador de la entidad es incorrecto.</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Inscripción de dominio:</translation>
<translation id="1344588688991793829">Configuración de la función Autocompletar de Chromium…</translation>
<translation id="1426410128494586442">Sí</translation>
+<translation id="1430915738399379752">Imprimir</translation>
<translation id="1455235771979731432">Se produjo un problema al verificar la tarjeta. Verifica la conexión a Internet y vuelve a intentarlo.</translation>
<translation id="1491151370853475546">Volver a cargar esta página</translation>
<translation id="1549470594296187301">JavaScript debe estar habilitado para usar esta función.</translation>
-<translation id="1639239467298939599">Cargando</translation>
<translation id="1640180200866533862">Políticas de usuario</translation>
<translation id="1644184664548287040">La configuración de red no es válida y no se pudo importar.</translation>
-<translation id="1693754753824026215">La página en <ph name="SITE"/> dice:</translation>
+<translation id="1655462015569774233">{1,plural, =1{El servidor no logró comprobar si el dominio es <ph name="DOMAIN" />; el certificado de seguridad venció ayer. Es posible que esto se deba a una configuración incorrecta o a que un atacante haya interceptado la conexión. Actualmente, el reloj de la computadora está configurado en la siguiente fecha: <ph name="CURRENT_DATE" />. ¿Es correcto? De no ser así, corrige el reloj del sistema y, a continuación, actualiza la página.}other{El servidor no logró comprobar si el dominio es <ph name="DOMAIN" />; el certificado de seguridad venció hace # días. Es posible que esto se deba a una configuración incorrecta o a que un atacante haya interceptado la conexión. Actualmente, el reloj de la computadora está configurado en la siguiente fecha: <ph name="CURRENT_DATE" />. ¿Es correcto? De no ser así, corrige el reloj del sistema y, a continuación, actualiza la página.}}</translation>
+<translation id="168841957122794586">El certificado del servidor contiene una clave criptográfica no segura.</translation>
+<translation id="1693754753824026215">La página en <ph name="SITE" /> dice:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el sistema operativo del dispositivo no confía en el certificado de seguridad. Es posible que esto se deba a una configuración incorrecta o a que un atacante interceptó la conexión.</translation>
<translation id="1821930232296380041">Solicitud o parámetros de solicitud no válidos</translation>
-<translation id="1853748787962613237">Error al mostrar el artículo</translation>
<translation id="1871208020102129563">El proxy está configurado para usar servidores proxy fijos, no una URL de script .pac.</translation>
-<translation id="1875753206475436906">tipo heurístico: <ph name="HEURISTIC_TYPE"/>
- tipo de servidor: <ph name="SERVER_TYPE"/>
- firma de campo: <ph name="FIELD_SIGNATURE"/>
- firma de formulario: <ph name="FORM_SIGNATURE"/>
- id de experimento: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Ir a <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Marcadores de <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Ir a <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Marcadores de <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Error de serialización</translation>
+<translation id="1974060860693918893">Avanzada</translation>
<translation id="2025186561304664664">El proxy se estableció en configuración automática.</translation>
<translation id="2025623846716345241">Confirmar la recarga</translation>
-<translation id="2030481566774242610">¿Quisiste decir: <ph name="LINK"/>?</translation>
-<translation id="2053553514270667976">Código ZIP</translation>
+<translation id="2030481566774242610">¿Quisiste decir: <ph name="LINK" />?</translation>
+<translation id="2053553514270667976">Código Postal</translation>
<translation id="20817612488360358">Se ha establecido la configuración de proxy del sistema, pero también se ha especificado una configuración explícita de proxy.</translation>
<translation id="2094505752054353250">El dominio no coincide.</translation>
<translation id="2096368010154057602">Departamento</translation>
<translation id="2113977810652731515">Tarjeta</translation>
-<translation id="2114841414352855701">Se ignoró porque fue anulada por <ph name="POLICY_NAME"/> .</translation>
+<translation id="2114841414352855701">Se ignoró porque fue anulada por <ph name="POLICY_NAME" /> .</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Marcadores del celular</translation>
+<translation id="2171101176734966184">Intentaste acceder a <ph name="DOMAIN" />, pero el servidor presentó un certificado firmado con un algoritmo de firma no seguro. Es posible que se hayan falsificado las credenciales de seguridad presentadas por el servidor y que este no sea el servidor esperado (es posible que hayas establecido comunicación con un atacante).</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2212735316055980242">No se encontró la política.</translation>
<translation id="2213606439339815911">Recuperando entradas…</translation>
<translation id="225207911366869382">Este valor ya no se utiliza para esta política.</translation>
<translation id="2262243747453050782">Error de HTTP</translation>
-<translation id="2270192940992995399">Error al buscar el artículo</translation>
-<translation id="2328300916057834155">Marcador no válido ignorado en el índice <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Experimentos no disponibles</translation>
+<translation id="229702904922032456">Un certificado raíz o intermedio venció.</translation>
+<translation id="2328300916057834155">Marcador no válido ignorado en el índice <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Otros marcadores</translation>
<translation id="2359808026110333948">Continuar</translation>
<translation id="2367567093518048410">Nivel</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="2396249848217231973">&amp;Deshacer Eliminar</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="2455981314101692989">Esta página web ha inhabilitado la función de rellenado automático para este formulario.</translation>
<translation id="2479410451996844060">URL de búsqueda no válida</translation>
+<translation id="2491120439723279231">El certificado del servidor contiene errores.</translation>
<translation id="2495083838625180221">Analizador de JSON</translation>
<translation id="2498091847651709837">Escanear tarjeta nueva</translation>
<translation id="2556876185419854533">&amp;Deshacer Editar</translation>
-<translation id="2581221116934462656">¿Quieres que <ph name="PRODUCT_NAME"/> ofrezca traducir <ph name="LANGUAGE_NAME"/> páginas de este sitio la próxima vez?</translation>
+<translation id="2581221116934462656">¿Quieres que <ph name="PRODUCT_NAME" /> ofrezca traducir <ph name="LANGUAGE_NAME" /> páginas de este sitio la próxima vez?</translation>
<translation id="2587841377698384444">ID de API de directorio:</translation>
<translation id="2597378329261239068">Este documento está protegido por contraseña. Ingresa una contraseña.</translation>
+<translation id="2625385379895617796">El reloj está adelantado</translation>
<translation id="2639739919103226564">Estado:</translation>
+<translation id="2653659639078652383">Enviar</translation>
<translation id="2704283930420550640">El valor no coincide con el formato.</translation>
<translation id="2721148159707890343">Solicitud correcta</translation>
+<translation id="2728127805433021124">El certificado del servidor está firmado con un algoritmo de firma no seguro.</translation>
<translation id="2774256287122201187">Puedes continuar. Si accedes a la página, esta advertencia no volverá a aparecer durante cinco minutos.</translation>
<translation id="277499241957683684">Falta un registro de dispositivo.</translation>
<translation id="2835170189407361413">Eliminar formulario</translation>
-<translation id="2855922900409897335">Verificar tu <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Verificar tu <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el certificado de seguridad venció. Es posible que esto se deba a una configuración incorrecta o a un atacante que interceptó la conexión. La hora actual del reloj de la computadora es <ph name="CURRENT_TIME" />. ¿Es correcta? De lo contrario, corrige la hora del sistema y actualiza la página.</translation>
+<translation id="2922350208395188000">No se puede comprobar el certificado del servidor.</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="2958431318199492670">La configuración de red no cumple con el estándar ONC. Es posible que no se importen algunas partes de la configuración.</translation>
<translation id="2972581237482394796">&amp;Rehacer</translation>
-<translation id="3010559122411665027">Entrada de lista &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Entrada de lista "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Tipo de política incorrecto</translation>
<translation id="3105172416063519923">ID de recurso:</translation>
<translation id="3145945101586104090">Se produjo un error al decodificar respuesta.</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Isla</translation>
<translation id="3219579145727097045">Ingresa la fecha de vencimiento y el CVC de 4 dígitos que figura en el frente de la tarjeta de crédito.</translation>
-<translation id="3228969707346345236">Falló la traducción debido a que la página ya se encuentra en <ph name="LANGUAGE"/>.</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="3228969707346345236">Falló la traducción debido a que la página ya se encuentra en <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Deshacer Reorganizar</translation>
+<translation id="3286538390144397061">Reiniciar ahora</translation>
<translation id="333371639341676808">Evita que esta página cree cuadros de diálogo adicionales.</translation>
-<translation id="3369366829301677151">Actualizar y verificar tu <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">configuración</translation>
+<translation id="3369192424181595722">Error de reloj</translation>
+<translation id="3369366829301677151">Actualizar y verificar tu <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Desaprovisionado</translation>
<translation id="3377188786107721145">Error al analizar la política</translation>
<translation id="3380365263193509176">Error desconocido</translation>
<translation id="3380864720620200369">ID de cliente:</translation>
<translation id="3427342743765426898">&amp;Rehacer Editar</translation>
+<translation id="3435896845095436175">Habilitar</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Obtener intervalo:</translation>
+<translation id="3462200631372590220">Ocultar detalles avanzados</translation>
+<translation id="3528171143076753409">El certificado del servidor no es de confianza.</translation>
<translation id="3542684924769048008">Utilizar la contraseña para:</translation>
<translation id="3583757800736429874">&amp;Rehacer Mover</translation>
<translation id="3623476034248543066">Mostrar valor</translation>
+<translation id="3648607100222897006">Estas funciones experimentales pueden modificarse, dejar de funcionar o desaparecer en cualquier momento. No ofrecemos ninguna garantía para lo que pueda ocurrir si activas alguno de estos experimentos, y es posible que tu navegador se bloquee repentinamente. Bromas aparte, ten en cuenta que el navegador puede eliminar todos tus datos y que tu seguridad y tu privacidad se podrían ver comprometidas de forma inesperada. Cualquier experimento que actives, se activará para todos los usuarios de este navegador, así que te recomendamos que actúes con precaución.</translation>
<translation id="3650584904733503804">Validación correcta</translation>
<translation id="370665806235115550">Cargando...</translation>
<translation id="3712624925041724820">Licencias agotadas</translation>
<translation id="3739623965217189342">Vínculo copiado</translation>
<translation id="375403751935624634">Falló la traducción debido a un error de servidor.</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>
<translation id="3885155851504623709">Parroquia</translation>
<translation id="3934680773876859118">No se pudo cargar el documento PDF</translation>
<translation id="3963721102035795474">Modo de lectura</translation>
<translation id="4030383055268325496">&amp;Deshacer Agregar</translation>
-<translation id="4058922952496707368">Clave &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ADVERTENCIA</translation>
+<translation id="4058922952496707368">Clave "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">El proxy está configurado para usar una URL de script .pac, no servidores proxy fijos.</translation>
<translation id="409504436206021213">No volver a cargar</translation>
<translation id="4103249731201008433">El número de serie del dispositivo no es válido.</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Firma no válida</translation>
<translation id="4269787794583293679">(Sin nombre de usuario)</translation>
<translation id="4300246636397505754">Sugerencias para padres</translation>
-<translation id="4372948949327679948">Valor <ph name="VALUE_TYPE"/> esperado.</translation>
+<translation id="4325863107915753736">No se pudo encontrar el artículo</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="4394049700291259645">Inhabilitar</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="443673843213245140">Se inhabilitó el uso de un proxy, pero se especificó una configuración explícita de proxy.</translation>
-<translation id="4506176782989081258">Error de validación: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Error de validación: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">¿Confirmas que quieres quitar la dirección de Chrome?</translation>
<translation id="4594403342090139922">&amp;Deshacer Eliminar</translation>
<translation id="4607653538520819196">Reducir datos no puede transmitir esta página por proxy.</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="4726672564094551039">Volver a cargar políticas</translation>
+<translation id="4728558894243024398">Plataforma</translation>
+<translation id="4771973620359291008">Se ha producido un error desconocido.</translation>
<translation id="4800132727771399293">Verifica la fecha de vencimiento y el CVC, y vuelve a intentarlo.</translation>
<translation id="4813512666221746211">Error de red</translation>
+<translation id="4816492930507672669">Ajustar a la página</translation>
<translation id="4850886885716139402">Ver</translation>
-<translation id="4923417429809017348">Esta página ha sido traducida desde un idioma desconocido a <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Esta página ha sido traducida desde un idioma desconocido a <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Debe especificarse un valor.</translation>
<translation id="4968547170521245791">No se puede transmitir por proxy</translation>
-<translation id="498957508165411911">¿Quieres traducir del <ph name="ORIGINAL_LANGUAGE"/> al <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">¿Quieres traducir del <ph name="ORIGINAL_LANGUAGE" /> al <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">La memoria auxiliar se encuentra en mal estado.</translation>
<translation id="5031870354684148875">Acerca de Google Traductor</translation>
+<translation id="5045550434625856497">Contraseña incorrecta</translation>
+<translation id="5087286274860437796">El certificado del servidor no es válido en este momento.</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="5145883236150621069">Código de error en la respuesta de la política</translation>
<translation id="5172758083709347301">Equipo</translation>
-<translation id="5179510805599951267">¿No está en <ph name="ORIGINAL_LANGUAGE"/>? Informa este error</translation>
+<translation id="5179510805599951267">¿No está en <ph name="ORIGINAL_LANGUAGE" />? Informa este error</translation>
<translation id="5190835502935405962">Barra de marcadores</translation>
+<translation id="5199729219167945352">Experimentos</translation>
+<translation id="5251803541071282808">Nube</translation>
<translation id="5295309862264981122">Confirmar navegación</translation>
<translation id="5299298092464848405">Error al analizar la política</translation>
+<translation id="5316812925700871227">Girar a la izquierda</translation>
<translation id="5317780077021120954">Guardar</translation>
<translation id="536296301121032821">Error al almacenar la configuración de la política</translation>
-<translation id="5439770059721715174">Error de validación de esquema en &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Error de validación de esquema en "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Marca de tiempo de política incorrecta</translation>
<translation id="5470861586879999274">&amp;Rehacer Editar</translation>
<translation id="5509780412636533143">Marcadores administrados</translation>
<translation id="5523118979700054094">Nombre de la política</translation>
<translation id="552553974213252141">¿Se extrajo el texto correctamente?</translation>
<translation id="5540224163453853">No se pudo encontrar el artículo solicitado.</translation>
+<translation id="5556459405103347317">Cargar de nuevo</translation>
<translation id="5565735124758917034">Activo</translation>
<translation id="560412284261940334">No se admite la administración.</translation>
<translation id="5629630648637658800">Error al cargar la configuración de la política</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Usuario actual</translation>
<translation id="5813119285467412249">&amp;Rehacer Agregar</translation>
<translation id="5872918882028971132">Sugerencias para padres</translation>
-<translation id="587701087903783706">Cerrar la vista optimizada para celulares</translation>
<translation id="59107663811261420">Google Payments no admite este tipo de tarjeta para este comerciante. Selecciona otra tarjeta.</translation>
+<translation id="5975083100439434680">Alejar</translation>
<translation id="5989320800837274978">No se especifican servidores proxy fijos ni URL de secuencias de comandos .pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Cerrar</translation>
+<translation id="6060685159320643512">Cuidado, estos experimentos pueden dañarte</translation>
+<translation id="6151417162996330722">El certificado de servidor tiene un período de validez demasiado extenso.</translation>
<translation id="6154808779448689242">El token de política devuelto no coincide con el token actual.</translation>
<translation id="6165508094623778733">Más información</translation>
<translation id="6259156558325130047">&amp;Rehacer Reorganizar</translation>
-<translation id="6263376278284652872">Marcadores de <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Marcadores de <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Código postal</translation>
<translation id="6337534724793800597">Filtrar políticas por nombre</translation>
+<translation id="6387478394221739770">Si estás interesado en probar nuevas e interesantes funciones de Chrome, visita nuestro canal beta en chrome.com/beta.</translation>
+<translation id="6426993025560594914">Todos los experimentos están disponibles en tu plataforma.</translation>
<translation id="6445051938772793705">País</translation>
<translation id="6458467102616083041">Se ignora porque la política inhabilita la búsqueda predeterminada.</translation>
<translation id="647261751007945333">Políticas de dispositivos</translation>
<translation id="6512448926095770873">Abandonar esta página</translation>
<translation id="6529602333819889595">&amp;Rehacer Eliminar</translation>
<translation id="6550675742724504774">Opciones</translation>
-<translation id="6597614308054261376">Estás intentando acceder a <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. En este momento, Reducir datos no puede transmitir esta página por proxy.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Búsqueda</translation>
+<translation id="6597614308054261376">Estás intentando acceder a <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. En este momento, Reducir datos no puede transmitir esta página por proxy.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Búsqueda</translation>
<translation id="6644283850729428850">Esta política no ha sido aprobada.</translation>
<translation id="6646897916597483132">Ingresa el CVC de 4 dígitos que figura en el frente de la tarjeta.</translation>
+<translation id="674375294223700098">Error de certificado de servidor desconocido.</translation>
<translation id="6753269504797312559">Valor de la política</translation>
<translation id="6831043979455480757">Traducir</translation>
<translation id="6839929833149231406">Área</translation>
<translation id="6874604403660855544">&amp;Rehacer Agregar</translation>
<translation id="6891596781022320156">No se admite el nivel de políticas.</translation>
<translation id="6915804003454593391">Usuario:</translation>
+<translation id="6957887021205513506">El certificado del servidor parece falso.</translation>
<translation id="6965382102122355670">Aceptar</translation>
<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="6980028882292583085">Alerta de Javascript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Intentaste acceder a <ph name="DOMAIN" />, pero el certificado de servidor tenía un período de validez demasiado extenso para ser fiable.</translation>
<translation id="7087282848513945231">Condado</translation>
-<translation id="7108649287766967076">Se produjo un error en la traducción al <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="7108649287766967076">Se produjo un error en la traducción al <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="7139724024395191329">Emirato</translation>
+<translation id="7179921470347911571">Reiniciar ahora</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="7186367841673660872">Esta página se tradujo de<ph name="ORIGINAL_LANGUAGE" />a<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Buscar <ph name="SEARCH_TERMS"/> con <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Buscar <ph name="SEARCH_TERMS" /> con <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">No se puede establecer una conexión privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora del equipo (<ph name="DATE_AND_TIME" />) son incorrectas.</translation>
<translation id="7275334191706090484">Marcadores administrados</translation>
<translation id="7298195798382681320">Recomendada</translation>
<translation id="7334320624316649418">&amp;Rehacer Reorganizar</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obligatoria</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="7568593326407688803">Esta página está en<ph name="ORIGINAL_LANGUAGE"/>¿Quieres traducirla?</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="7568593326407688803">Esta página está en<ph name="ORIGINAL_LANGUAGE" />¿Quieres traducirla?</translation>
<translation id="7569952961197462199">¿Confirmas que quieres quitar la tarjeta de crédito de Chrome?</translation>
-<translation id="7600965453749440009">Nunca traducir <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">El valor <ph name="VALUE"/> está fuera del rango.</translation>
+<translation id="7592362899630581445">El certificado del servidor no cumple con las restricciones de nombre.</translation>
+<translation id="7600965453749440009">Nunca traducir <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">El valor <ph name="VALUE" /> está fuera del rango.</translation>
+<translation id="7674629440242451245">Si estás interesado en probar nuevas e interesantes funciones de Chrome, visita nuestro canal de programadores en chrome.com/dev.</translation>
<translation id="7752995774971033316">Sin administrar</translation>
+<translation id="7761701407923456692">El certificado del servidor no coincide con la dirección URL.</translation>
<translation id="777702478322588152">Prefectura</translation>
<translation id="7791543448312431591">Agregar</translation>
<translation id="7805768142964895445">Estado</translation>
<translation id="7813600968533626083">¿Confirmas que quieres quitar la sugerencia de formulario de Chrome?</translation>
<translation id="7887683347370398519">Verifica tu CVC y vuelve a intentarlo.</translation>
<translation id="7935318582918952113">Filtro de DOM</translation>
+<translation id="7938958445268990899">El certificado del servidor aún no es válido.</translation>
<translation id="7956713633345437162">Marcadores del celular</translation>
<translation id="7961015016161918242">Nunca</translation>
<translation id="7977590112176369853">&lt;escribir consulta&gt;</translation>
-<translation id="7983301409776629893">Siempre traducir del <ph name="ORIGINAL_LANGUAGE"/> al <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Siempre traducir del <ph name="ORIGINAL_LANGUAGE" /> al <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Marcadores de escritorio</translation>
<translation id="7995512525968007366">Sin especificar</translation>
-<translation id="8034522405403831421">Esta página está en <ph name="SOURCE_LANGUAGE"/>. ¿Quieres traducirla al <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Empresa (sin anulación)</translation>
+<translation id="8034522405403831421">Esta página está en <ph name="SOURCE_LANGUAGE" />. ¿Quieres traducirla al <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Error al visualizar artículo</translation>
<translation id="8091372947890762290">La activación está pendiente en el servidor.</translation>
<translation id="8194797478851900357">&amp;Deshacer Mover</translation>
-<translation id="8201077131113104583">URL de actualización no válida para la extensión con ID &quot;<ph name="EXTENSION_ID"/>&quot;</translation>
+<translation id="8201077131113104583">URL de actualización no válida para la extensión con ID "<ph name="EXTENSION_ID" />"</translation>
<translation id="8208216423136871611">No guardar</translation>
<translation id="8218327578424803826">Ubicación asignada:</translation>
<translation id="8249320324621329438">Se obtuvo por última vez:</translation>
+<translation id="8294431847097064396">Fuente</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="8311778656528046050">¿Estás seguro de que quieres volver a cargar esta página?</translation>
<translation id="8349305172487531364">Barra de marcadores</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Se aplica a</translation>
<translation id="8530504477309582336">Google Payments no admite este tipo de tarjeta. Selecciona otra tarjeta.</translation>
<translation id="8553075262323480129">Falló la traducción debido a que no se pudo determinar el idioma de la página.</translation>
-<translation id="8571890674111243710">Traduciendo página a <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">No se puede establecer una conexión privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora del dispositivo (<ph name="DATE_AND_TIME" />) son incorrectas.</translation>
+<translation id="8571890674111243710">Traduciendo página a <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Restablecer todos los valores predeterminados</translation>
<translation id="8713130696108419660">Firma inicial no válida</translation>
<translation id="8725066075913043281">Intentar nuevamente</translation>
+<translation id="8738058698779197622">Para establecer una conexión segura, el reloj debe estar configurado correctamente. Esto se debe a que los certificados que usan los sitios web para su identificación solo son válidos por períodos de tiempo específicos. Debido a que la configuración del reloj del dispositivo es incorrecta, Chromium no puede verificar estos certificados.</translation>
<translation id="8790007591277257123">&amp;Rehacer Eliminar</translation>
<translation id="8804164990146287819">Política de privacidad</translation>
+<translation id="8820817407110198400">Marcadores</translation>
<translation id="8824019021993735287">Chrome no pudo verificar tu tarjeta en este momento. Vuelve a intentarlo más tarde.</translation>
<translation id="8834246243508017242">Habilitar Autocompletar con Contactos…</translation>
<translation id="883848425547221593">Otros marcadores</translation>
+<translation id="884923133447025588">No se ha encontrado ningún mecanismo de revocación.</translation>
<translation id="8866481888320382733">Error al analizar la configuración de la política</translation>
<translation id="8876793034577346603">No se pudo analizar la configuración de red.</translation>
<translation id="8891727572606052622">Modo proxy no válido</translation>
-<translation id="8940229512486821554">Ejecutar <ph name="EXTENSION_NAME"/> comando: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Este experimento no está disponible en tu plataforma.</translation>
+<translation id="8903921497873541725">Acercar</translation>
+<translation id="8932102934695377596">El reloj está atrasado</translation>
+<translation id="8940229512486821554">Ejecutar <ph name="EXTENSION_NAME" /> comando: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">El certificado del servidor ha caducado.</translation>
<translation id="8988760548304185580">Ingresa la fecha de vencimiento y el CVC de 3 dígitos que figura en el dorso de la tarjeta.</translation>
-<translation id="9020542370529661692">Esta página se tradujo al <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="901974403500617787">El propietario es el único que puede especificar las marcas que se aplican a todo el sistema: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Esta página se tradujo al <ph name="TARGET_LANGUAGE" />.</translation>
+<translation id="9049981332609050619">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor presentó un certificado no válido.</translation>
<translation id="9125941078353557812">Ingresa el CVC de 3 dígitos que figura en el dorso de la tarjeta.</translation>
<translation id="9137013805542155359">Mostrar original</translation>
<translation id="9148507642005240123">&amp;Deshacer Editar</translation>
<translation id="9154176715500758432">Permanecer en esta página</translation>
<translation id="9170848237812810038">&amp;Deshacer</translation>
+<translation id="917450738466192189">El certificado del servidor no es válido.</translation>
+<translation id="9187827965378254003">Parece que actualmente no hay ningún experimento disponible.</translation>
<translation id="9207861905230894330">Error al agregar artículo</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">BORRAR FORMULARIO</translation>
+<translation id="988159990683914416">Build para desarrolladores</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_es.xtb b/chromium/components/strings/components_strings_es.xtb
index af84563b808..1c160432598 100644
--- a/chromium/components/strings/components_strings_es.xtb
+++ b/chromium/components/strings/components_strings_es.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="es">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="es">
+<translation id="1032854598605920125">Girar hacia la derecha</translation>
<translation id="1055184225775184556">&amp;Deshacer acción de añadir</translation>
<translation id="106701514854093668">Marcadores del ordenador</translation>
-<translation id="1103523840287552314">Traducir siempre el <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Se ajusta al ancho</translation>
+<translation id="1103523840287552314">Traducir siempre el <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Deshacer reorganización</translation>
<translation id="111844081046043029">¿Seguro que quieres abandonar esta página?</translation>
<translation id="112840717907525620">Caché de política correcta</translation>
<translation id="1132774398110320017">Configuración de la función Autocompletar de Chrome...</translation>
-<translation id="1152921474424827756">Accede a una <ph name="BEGIN_LINK"/>copia almacenada en caché<ph name="END_LINK"/> de <ph name="URL"/></translation>
+<translation id="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="1152921474424827756">Accede a una <ph name="BEGIN_LINK" />copia almacenada en caché<ph name="END_LINK" /> de <ph name="URL" /></translation>
+<translation id="121201262018556460">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado que contiene una clave no segura. Es posible que alguien haya descifrado la clave privada y que hayas accedido a la página de esa persona en lugar de establecer conexión con el servidor.</translation>
<translation id="1227224963052638717">Política desconocida</translation>
<translation id="1227633850867390598">Ocultar valor</translation>
<translation id="1228893227497259893">Identificador de entidad incorrecto</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Dominio de registro:</translation>
<translation id="1344588688991793829">Configuración de la función Autocompletar de Chromium...</translation>
<translation id="1426410128494586442">Sí</translation>
+<translation id="1430915738399379752">Imprimir</translation>
<translation id="1455235771979731432">Se ha producido un problema al verificar tu tarjeta. Comprueba tu conexión a Internet y vuelve a intentarlo.</translation>
<translation id="1491151370853475546">Volver a cargar esta página</translation>
<translation id="1549470594296187301">JavaScript debe estar habilitado para utilizar esta función.</translation>
-<translation id="1639239467298939599">Cargando</translation>
<translation id="1640180200866533862">Políticas de usuario</translation>
<translation id="1644184664548287040">La configuración de red no es válida y no se ha podido importar.</translation>
-<translation id="1693754753824026215">Mensaje de la página <ph name="SITE"/>:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad caducó ayer. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. El reloj de tu ordenador está establecido actualmente en las <ph name="CURRENT_DATE" />. ¿Es correcto? Si no lo es, corrige el reloj del sistema y, a continuación, actualiza esta página.}other{Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad caducó hace # días. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. El reloj de tu ordenador está establecido actualmente en las <ph name="CURRENT_DATE" />. ¿Es correcto? Si no lo es, corrige el reloj del sistema y, a continuación, actualiza esta página.}}</translation>
+<translation id="168841957122794586">El certificado del servidor contiene una clave criptográfica no segura.</translation>
+<translation id="1693754753824026215">Mensaje de la página <ph name="SITE" />:</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="1734864079702812349">American Express</translation>
+<translation id="1763864636252898013">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, el sistema operativo de tu dispositivo no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
<translation id="1821930232296380041">Parámetros de solicitud o solicitud no válidos</translation>
-<translation id="1853748787962613237">Se ha producido un error al mostrar el artículo.</translation>
<translation id="1871208020102129563">Se ha configurado el proxy de forma que use servidores proxy fijos, en lugar de una URL de secuencia de comandos .pac.</translation>
-<translation id="1875753206475436906">tipo heurístico: <ph name="HEURISTIC_TYPE"/>
- tipo de servidor: <ph name="SERVER_TYPE"/>
- firma de campo: <ph name="FIELD_SIGNATURE"/>
- firma de formulario: <ph name="FORM_SIGNATURE"/>
- ID del experimento: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Ir a <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Marcadores de <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Ir a <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Marcadores de <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Error de serialización</translation>
+<translation id="1974060860693918893">Opciones avanzadas</translation>
<translation id="2025186561304664664">Se ha establecido que el proxy se configure automáticamente.</translation>
<translation id="2025623846716345241">Confirmar que quieres volver a cargar la página</translation>
-<translation id="2030481566774242610">¿Querías decir <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">¿Querías decir <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Código postal</translation>
<translation id="20817612488360358">Se ha establecido la configuración del proxy del sistema, pero también se han especificado ajustes de proxy explícitos.</translation>
<translation id="2094505752054353250">El dominio no coincide</translation>
<translation id="2096368010154057602">Departamento</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="2114841414352855701">Se ha ignorado la política porque la anula <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Cliente nativo</translation>
<translation id="213826338245044447">Marcadores del móvil</translation>
+<translation id="2171101176734966184">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado firmado con un algoritmo de firma no seguro. Una posible causa de este problema es que se hayan falsificado las credenciales de seguridad presentadas por el servidor y que hayas accedido a la página de un atacante en lugar de establecer conexión con el servidor en cuestión.</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2212735316055980242">Política no encontrada</translation>
<translation id="2213606439339815911">Recuperando entradas...</translation>
<translation id="225207911366869382">Este valor ya no se utiliza para esta política.</translation>
<translation id="2262243747453050782">Error de HTTP</translation>
-<translation id="2270192940992995399">Se ha producido un error al buscar el artículo.</translation>
-<translation id="2328300916057834155">Se ha ignorado un marcador no válido en el índice <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Experimentos no disponibles</translation>
+<translation id="229702904922032456">Ha caducado un certificado raíz o intermedio.</translation>
+<translation id="2328300916057834155">Se ha ignorado un marcador no válido en el índice <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Otros marcadores</translation>
<translation id="2359808026110333948">Continuar</translation>
<translation id="2367567093518048410">Nivel</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="2396249848217231973">&amp;Deshacer eliminación</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="2455981314101692989">Esta página ha inhabilitado la opción de autocompletar para este formulario.</translation>
<translation id="2479410451996844060">La URL de búsqueda no es válida.</translation>
+<translation id="2491120439723279231">El certificado del servidor contiene errores.</translation>
<translation id="2495083838625180221">Analizador de archivos JSON</translation>
<translation id="2498091847651709837">Escanear nueva tarjeta</translation>
<translation id="2556876185419854533">&amp;Deshacer edición</translation>
-<translation id="2581221116934462656">¿Quieres que <ph name="PRODUCT_NAME"/> ofrezca la posibilidad de traducir las páginas de este sitio escritas en <ph name="LANGUAGE_NAME"/> la próxima vez?</translation>
+<translation id="2581221116934462656">¿Quieres que <ph name="PRODUCT_NAME" /> ofrezca la posibilidad de traducir las páginas de este sitio escritas en <ph name="LANGUAGE_NAME" /> la próxima vez?</translation>
<translation id="2587841377698384444">ID de la API del directorio:</translation>
<translation id="2597378329261239068">Este documento está protegido por contraseña. Introduce una contraseña.</translation>
+<translation id="2625385379895617796">Tu reloj está adelantado</translation>
<translation id="2639739919103226564">Estado:</translation>
+<translation id="2653659639078652383">Enviar</translation>
<translation id="2704283930420550640">El valor no coincide con el formato.</translation>
<translation id="2721148159707890343">Solicitud correcta</translation>
+<translation id="2728127805433021124">El certificado del servidor está firmado con un algoritmo de firma no seguro.</translation>
<translation id="2774256287122201187">Puedes continuar. Si accedes a la página, esta advertencia no volverá a aparecer durante cinco minutos.</translation>
<translation id="277499241957683684">Falta un registro de dispositivo.</translation>
<translation id="2835170189407361413">Eliminar formulario</translation>
-<translation id="2855922900409897335">Verifica tu <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Verifica tu <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Este servidor no ha podido probar que su dominio sea <ph name="DOMAIN" />, ya que su certificado de seguridad ha caducado. Este problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión. La hora actual del reloj de tu ordenador es <ph name="CURRENT_TIME" />. ¿Es correcta? Si no lo es, debes corregir la hora del sistema y, a continuación, actualizar esta página.</translation>
+<translation id="2922350208395188000">No es posible comprobar el certificado del servidor.</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="2958431318199492670">La configuración de red no cumple el estándar ONC. Es posible que no se importen partes de la configuración.</translation>
<translation id="2972581237482394796">&amp;Rehacer</translation>
-<translation id="3010559122411665027">Entrada de lista &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Entrada de lista "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Tipo de política incorrecto</translation>
<translation id="3105172416063519923">ID de recurso:</translation>
<translation id="3145945101586104090">Error al decodificar respuesta</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Isla</translation>
<translation id="3219579145727097045">Introduce la fecha de caducidad y el código CVC de cuatro dígitos que aparece en el anverso de tu tarjeta</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="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="3228969707346345236">La traducción no ha podido realizarse correctamente porque la página ya está en <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Deshacer reorganización</translation>
+<translation id="3286538390144397061">Reiniciar ahora</translation>
<translation id="333371639341676808">Evita que esta página cree cuadros de diálogo adicionales.</translation>
-<translation id="3369366829301677151">Actualiza y verifica tu <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">configuración</translation>
+<translation id="3369192424181595722">Error del reloj</translation>
+<translation id="3369366829301677151">Actualiza y verifica tu <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Desaprovisionado</translation>
<translation id="3377188786107721145">Error al analizar la política</translation>
<translation id="3380365263193509176">Error desconocido</translation>
<translation id="3380864720620200369">ID de cliente:</translation>
<translation id="3427342743765426898">&amp;Rehacer edición</translation>
+<translation id="3435896845095436175">Habilitar</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Intervalo de comprobación:</translation>
+<translation id="3462200631372590220">Ocultar opciones avanzadas</translation>
+<translation id="3528171143076753409">El certificado de servidor no es de confianza.</translation>
<translation id="3542684924769048008">Utilizar contraseña para:</translation>
<translation id="3583757800736429874">&amp;Rehacer movimiento</translation>
<translation id="3623476034248543066">Mostrar valor</translation>
+<translation id="3648607100222897006">Estas funciones experimentales pueden cambiar, dejar de funcionar o desaparecer en cualquier momento. No ofrecemos ningún tipo de garantía de lo que pueda ocurrir si se habilita alguna de estas funciones experimentales, y es posible que el navegador se bloquee repentinamente. Bromas aparte, ten en cuenta que el navegador puede eliminar todos tus datos y que tu seguridad y tu privacidad se podrían ver comprometidas de forma inesperada. Cualquier experimento que habilites se habilitará para todos los usuarios del navegador, así que te recomendamos que actúes con precaución.</translation>
<translation id="3650584904733503804">Validación correcta</translation>
<translation id="370665806235115550">Cargando...</translation>
<translation id="3712624925041724820">Licencias agotadas</translation>
<translation id="3739623965217189342">Enlace copiado</translation>
<translation id="375403751935624634">Se ha producido un error de traducción debido a un problema con el servidor.</translation>
<translation id="385051799172605136">Atrás</translation>
+<translation id="3858027520442213535">Actualizar fecha y hora</translation>
<translation id="3884278016824448484">Identificador de dispositivo en conflicto</translation>
<translation id="3885155851504623709">Parroquia</translation>
<translation id="3934680773876859118">Se ha producido un error al cargar el documento PDF.</translation>
<translation id="3963721102035795474">Modo de lectura</translation>
<translation id="4030383055268325496">&amp;Deshacer acción de añadir</translation>
-<translation id="4058922952496707368">Clave &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ADVERTENCIA</translation>
+<translation id="4058922952496707368">Clave "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Se ha configurado el proxy para que use una URL de secuencia de comandos .pac, en lugar de servidores proxy fijos.</translation>
<translation id="409504436206021213">No volver a cargar esta página</translation>
<translation id="4103249731201008433">El número de serie del dispositivo no es válido.</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Firma errónea</translation>
<translation id="4269787794583293679">(Ningún nombre de usuario)</translation>
<translation id="4300246636397505754">Sugerencias de padres</translation>
-<translation id="4372948949327679948">Se esperaba un valor <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Error al buscar el artículo</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="4394049700291259645">Inhabilitar</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="443673843213245140">Se ha inhabilitado el uso de un servidor proxy, pero se han especificado ajustes de proxy explícitos.</translation>
-<translation id="4506176782989081258">Error de validación: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Error de validación: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">¿Eliminar dirección de Chrome?</translation>
<translation id="4594403342090139922">&amp;Deshacer eliminación</translation>
<translation id="4607653538520819196">El Economizador de datos no puede enviar esta página a un proxy.</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="4726672564094551039">Volver a cargar políticas</translation>
+<translation id="4728558894243024398">Plataforma</translation>
+<translation id="4771973620359291008">Se ha producido un error desconocido.</translation>
<translation id="4800132727771399293">Comprueba la fecha de caducidad y el código CVC, y vuelve a intentarlo</translation>
<translation id="4813512666221746211">Error de red</translation>
+<translation id="4816492930507672669">Ajustar a página</translation>
<translation id="4850886885716139402">Ver</translation>
-<translation id="4923417429809017348">Esta página se ha traducido de un idioma desconocido al <ph name="LANGUAGE_LANGUAGE"/>.</translation>
+<translation id="4923417429809017348">Esta página se ha traducido de un idioma desconocido al <ph name="LANGUAGE_LANGUAGE" />.</translation>
<translation id="4926049483395192435">Se debe especificar un valor.</translation>
<translation id="4968547170521245791">No se puede enviar a un proxy</translation>
-<translation id="498957508165411911">¿Traducir del <ph name="ORIGINAL_LANGUAGE"/> al <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">¿Traducir del <ph name="ORIGINAL_LANGUAGE" /> al <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">El almacén secundario está en mal estado.</translation>
<translation id="5031870354684148875">Informacion del Traductor de Google</translation>
+<translation id="5045550434625856497">Contraseña incorrecta</translation>
+<translation id="5087286274860437796">El certificado del servidor no es válido en este momento.</translation>
<translation id="5089810972385038852">Estado</translation>
+<translation id="5094747076828555589">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, Chromium no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
<translation id="5095208057601539847">Provincia</translation>
<translation id="5145883236150621069">Código de error presente en respuesta de la política</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="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="5199729219167945352">Experimentos</translation>
+<translation id="5251803541071282808">Nube</translation>
<translation id="5295309862264981122">Confirmar navegación</translation>
<translation id="5299298092464848405">Error al analizar la política</translation>
+<translation id="5316812925700871227">Girar hacia la izquierda</translation>
<translation id="5317780077021120954">Guardar</translation>
<translation id="536296301121032821">Error al almacenar la configuración de la política</translation>
-<translation id="5439770059721715174">Error de validación de esquema en &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Error de validación de esquema en "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Marca de tiempo de política incorrecta</translation>
<translation id="5470861586879999274">&amp;Rehacer edición</translation>
<translation id="5509780412636533143">Marcadores administrados</translation>
<translation id="5523118979700054094">Nombre de la política</translation>
<translation id="552553974213252141">¿Se ha extraído el texto correctamente?</translation>
<translation id="5540224163453853">No se ha podido encontrar el artículo solicitado.</translation>
+<translation id="5556459405103347317">Cargar de nuevo</translation>
<translation id="5565735124758917034">Activo</translation>
<translation id="560412284261940334">Administración no admitida</translation>
<translation id="5629630648637658800">Error al cargar la configuración de la política</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Usuario actual</translation>
<translation id="5813119285467412249">&amp;Rehacer acción de añadir</translation>
<translation id="5872918882028971132">Sugerencias de padres</translation>
-<translation id="587701087903783706">Cerrar vista optimizada para móviles</translation>
<translation id="59107663811261420">Google Payments no admite este tipo de tarjeta para este comerciante. Selecciona otra.</translation>
+<translation id="5975083100439434680">Reducir</translation>
<translation id="5989320800837274978">No se han especificado servidores proxy fijos ni una URL de secuencia de comandos .pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Cerrar</translation>
+<translation id="6060685159320643512">¡Atención! Estos experimentos pueden ser peligrosos</translation>
+<translation id="6151417162996330722">El certificado del servidor tiene un período de validez demasiado largo.</translation>
<translation id="6154808779448689242">El token de política devuelto no coincide con el token actual.</translation>
<translation id="6165508094623778733">Más información</translation>
<translation id="6259156558325130047">&amp;Rehacer reorganización</translation>
-<translation id="6263376278284652872">Marcadores de <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Marcadores de <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Código postal</translation>
<translation id="6337534724793800597">Filtrar políticas por nombre</translation>
+<translation id="6387478394221739770">Si estás interesado en probar nuevas e interesantes funciones de Chrome, prueba nuestro canal beta en la página chrome.com/beta.</translation>
+<translation id="6426993025560594914">Todos los experimentos están disponibles en tu plataforma.</translation>
<translation id="6445051938772793705">País</translation>
<translation id="6458467102616083041">Se ha ignorado el valor porque se ha establecido una política que inhabilita la búsqueda predeterminada.</translation>
<translation id="647261751007945333">Políticas de dispositivos</translation>
<translation id="6512448926095770873">Abandonar esta página</translation>
<translation id="6529602333819889595">&amp;Rehacer eliminación</translation>
<translation id="6550675742724504774">Configuración</translation>
-<translation id="6597614308054261376">Estás intentando acceder a <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. En este momento, el Economizador de datos no puede enviar esta página a un proxy.</translation>
-<translation id="6628463337424475685">Búsqueda de <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Estás intentando acceder a <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. En este momento, el Economizador de datos no puede enviar esta página a un proxy.</translation>
+<translation id="6628463337424475685">Búsqueda de <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Esta política está obsoleta.</translation>
<translation id="6646897916597483132">Introduce el código CVC de cuatro dígitos que aparece en el anverso de tu tarjeta</translation>
+<translation id="674375294223700098">Error de certificado de servidor desconocido</translation>
<translation id="6753269504797312559">Valor de la política</translation>
<translation id="6831043979455480757">Traducir</translation>
<translation id="6839929833149231406">Área</translation>
<translation id="6874604403660855544">&amp;Rehacer acción de añadir</translation>
<translation id="6891596781022320156">No se admite el nivel de la política.</translation>
<translation id="6915804003454593391">Usuario:</translation>
+<translation id="6957887021205513506">El certificado del servidor parece ser falso.</translation>
<translation id="6965382102122355670">Aceptar</translation>
<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="6980028882292583085">Alerta de JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado cuyo período de validez es demasiado largo para que se considere de confianza.</translation>
<translation id="7087282848513945231">Condado</translation>
-<translation id="7108649287766967076">No se ha podido realizar la traducción al <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="7108649287766967076">No se ha podido realizar la traducción al <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="7139724024395191329">Emirato</translation>
+<translation id="7179921470347911571">Reiniciar ahora</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="7186367841673660872">Esta página se ha traducido del<ph name="ORIGINAL_LANGUAGE" />al<ph name="LANGUAGE_LANGUAGE" />.</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Buscar <ph name="SEARCH_TERMS"/> con <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Buscar <ph name="SEARCH_TERMS" /> con <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">No se puede establecer una conexión privada con <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora de tu ordenador (<ph name="DATE_AND_TIME" />) no son correctas.</translation>
<translation id="7275334191706090484">Marcadores administrados</translation>
<translation id="7298195798382681320">Recomendadas</translation>
<translation id="7334320624316649418">&amp;Rehacer reorganización</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obligatoria</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="7568593326407688803">Esta página está escrita en<ph name="ORIGINAL_LANGUAGE"/>¿Quieres traducirla?</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="7568593326407688803">Esta página está escrita en<ph name="ORIGINAL_LANGUAGE" />¿Quieres traducirla?</translation>
<translation id="7569952961197462199">¿Eliminar tarjeta de crédito de Chrome?</translation>
-<translation id="7600965453749440009">No traducir nunca del <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">El valor <ph name="VALUE"/> se encuentra fuera del intervalo.</translation>
+<translation id="7592362899630581445">El certificado del servidor incluye un nombre que está fuera de su cobertura.</translation>
+<translation id="7600965453749440009">No traducir nunca del <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">El valor <ph name="VALUE" /> se encuentra fuera del intervalo.</translation>
+<translation id="7674629440242451245">Si estás interesado en probar nuevas e interesantes funciones de Chrome, prueba el canal para desarrolladores en la página chrome.com/dev.</translation>
<translation id="7752995774971033316">No administrado</translation>
+<translation id="7761701407923456692">El certificado del servidor no coincide con la URL.</translation>
<translation id="777702478322588152">Prefectura</translation>
<translation id="7791543448312431591">Añadir</translation>
<translation id="7805768142964895445">Estado</translation>
<translation id="7813600968533626083">¿Eliminar sugerencia de formulario de Chrome?</translation>
<translation id="7887683347370398519">Comprueba el código CVC y vuelve a intentarlo</translation>
<translation id="7935318582918952113">Extractor de DOM</translation>
+<translation id="7938958445268990899">Aún no es válido el certificado de servidor.</translation>
<translation id="7956713633345437162">Marcadores del móvil</translation>
<translation id="7961015016161918242">Nunca</translation>
<translation id="7977590112176369853">&lt;introducir consulta&gt;</translation>
-<translation id="7983301409776629893">Traducir siempre del <ph name="ORIGINAL_LANGUAGE"/> al <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Traducir siempre del <ph name="ORIGINAL_LANGUAGE" /> al <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Marcadores del ordenador</translation>
<translation id="7995512525968007366">Sin especificar</translation>
-<translation id="8034522405403831421">Esta página está escrita en <ph name="SOURCE_LANGUAGE"/>. ¿Quieres traducirla al <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Empresa (sin anulación)</translation>
+<translation id="8034522405403831421">Esta página está escrita en <ph name="SOURCE_LANGUAGE" />. ¿Quieres traducirla al <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Se ha producido un error al ver el artículo.</translation>
<translation id="8091372947890762290">La activación está pendiente en el servidor.</translation>
<translation id="8194797478851900357">&amp;Deshacer movimiento</translation>
-<translation id="8201077131113104583">URL de actualización no válida para la extensión <ph name="EXTENSION_ID"/>.</translation>
+<translation id="8201077131113104583">URL de actualización no válida para la extensión <ph name="EXTENSION_ID" />.</translation>
<translation id="8208216423136871611">No guardar</translation>
<translation id="8218327578424803826">Ubicación asignada:</translation>
<translation id="8249320324621329438">Última comprobación:</translation>
+<translation id="8294431847097064396">Origen</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="8311778656528046050">¿Seguro que quieres volver a cargar esta página?</translation>
<translation id="8349305172487531364">Barra de marcadores</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Aplicable a</translation>
<translation id="8530504477309582336">Google Payments no admite este tipo de tarjeta. Selecciona otra.</translation>
<translation id="8553075262323480129">La traducción no se ha realizado correctamente porque no se ha podido determinar el idioma de la página.</translation>
-<translation id="8571890674111243710">Traduciendo página a <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">No se puede establecer una conexión privada con <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora de tu dispositivo (<ph name="DATE_AND_TIME" />) no son correctas.</translation>
+<translation id="8571890674111243710">Traduciendo página a <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Restablecer todo a su estado predeterminado</translation>
<translation id="8713130696108419660">Firma inicial incorrecta</translation>
<translation id="8725066075913043281">Volver a intentarlo</translation>
+<translation id="8738058698779197622">Para establecer una conexión segura, tu reloj debe estar correctamente configurado. Esto se debe a que los certificados utilizados por los sitios web para identificarse son solo válidos durante períodos específicos de tiempo. Dado que la hora de tu dispositivo no es correcta, Chromium no puede verificar estos certificados.</translation>
<translation id="8790007591277257123">&amp;Rehacer eliminación</translation>
<translation id="8804164990146287819">Política de privacidad</translation>
+<translation id="8820817407110198400">Marcadores</translation>
<translation id="8824019021993735287">Chrome no ha podido verificar tu tarjeta en este momento. Vuelve a intentarlo más tarde.</translation>
<translation id="8834246243508017242">Habilitar Autocompletar usando contactos…</translation>
<translation id="883848425547221593">Otros marcadores</translation>
+<translation id="884923133447025588">No se ha encontrado ningún mecanismo de revocación.</translation>
<translation id="8866481888320382733">Error al analizar la configuración de la política</translation>
<translation id="8876793034577346603">No se ha podido analizar la configuración de red.</translation>
<translation id="8891727572606052622">El modo de proxy no es válido.</translation>
-<translation id="8940229512486821554">Ejecuta el comando de <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Esta función experimental no está disponible en tu plataforma.</translation>
+<translation id="8903921497873541725">Acercar</translation>
+<translation id="8932102934695377596">Tu reloj está atrasado</translation>
+<translation id="8940229512486821554">Ejecuta el comando de <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">El certificado del servidor ha caducado.</translation>
<translation id="8988760548304185580">Introduce la fecha de caducidad y el código CVC de tres dígitos que aparece en el reverso de tu tarjeta</translation>
-<translation id="9020542370529661692">Esta página se ha traducido al <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Las opciones que se aplican a todo el sistema solo las puede establecer el propietario: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Esta página se ha traducido al <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado no válido.</translation>
<translation id="9125941078353557812">Introduce el código CVC de tres dígitos que aparece en el reverso de tu tarjeta</translation>
<translation id="9137013805542155359">Mostrar original</translation>
<translation id="9148507642005240123">&amp;Deshacer edición</translation>
<translation id="9154176715500758432">Permanecer en esta página</translation>
<translation id="9170848237812810038">&amp;Deshacer</translation>
+<translation id="917450738466192189">El certificado del servidor no es válido.</translation>
+<translation id="9187827965378254003">Ohh, no hay experimentos disponibles.</translation>
<translation id="9207861905230894330">Se ha producido un error al añadir el artículo.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">BORRAR FORMULARIO</translation>
+<translation id="988159990683914416">Build para desarrolladores</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_et.xtb b/chromium/components/strings/components_strings_et.xtb
index 1bee8099213..2bc2ede5b71 100644
--- a/chromium/components/strings/components_strings_et.xtb
+++ b/chromium/components/strings/components_strings_et.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="et">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="et">
+<translation id="1032854598605920125">Pööra päripäeva</translation>
<translation id="1055184225775184556">&amp;Võta lisamine tagasi</translation>
<translation id="106701514854093668">Töölaua järjehoidjad</translation>
-<translation id="1103523840287552314">Tõlgi alati: <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Sobita laiusesse</translation>
+<translation id="1103523840287552314">Tõlgi alati: <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Võta korrastamine tagasi</translation>
<translation id="111844081046043029">Olete kindel, et soovite sellele lehelt lahkuda?</translation>
<translation id="112840717907525620">Reegli vahemälu töötab probleemideta</translation>
<translation id="1132774398110320017">Chrome'i automaattäite seaded ...</translation>
-<translation id="1152921474424827756">Hankige juurdepääs aadressi <ph name="URL"/> <ph name="BEGIN_LINK"/>vahemällu salvestatud koopiale<ph name="END_LINK"/></translation>
+<translation id="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="1152921474424827756">Hankige juurdepääs aadressi <ph name="URL" /> <ph name="BEGIN_LINK" />vahemällu salvestatud koopiale<ph name="END_LINK" /></translation>
+<translation id="121201262018556460">Proovisite jõuda saidile <ph name="DOMAIN" />, kuid server esitas nõrka võtit sisaldava sertifikaadi. Võimalik, et ründaja on privaatvõtme lahti murdnud ja tegemist ei pruugi olla oodatud serveriga (võimalik, et suhtlete ründajaga).</translation>
<translation id="1227224963052638717">Tundmatud eeskirjad.</translation>
<translation id="1227633850867390598">Peida väärtus</translation>
<translation id="1228893227497259893">Üksuse vale identifikaator</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Registreerimisdomeen:</translation>
<translation id="1344588688991793829">Chromiumi automaattäite seaded ...</translation>
<translation id="1426410128494586442">Jah</translation>
+<translation id="1430915738399379752">Printimine</translation>
<translation id="1455235771979731432">Kaardi kinnitamisel tekkis probleem. Kontrollige Interneti-ühendust ja proovige uuesti.</translation>
<translation id="1491151370853475546">Laadi leht uuesti</translation>
<translation id="1549470594296187301">Selle funktsiooni kasutamiseks peab JavaScript olema lubatud.</translation>
-<translation id="1639239467298939599">Laadimine</translation>
<translation id="1640180200866533862">Kasutajareeglid</translation>
<translation id="1644184664548287040">Võrgu seadistus on sobimatu ja seda ei saa importida.</translation>
-<translation id="1693754753824026215">Teade veebilehelt aadressil <ph name="SITE"/>:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />, selle turvasertifikaat aegus eile. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. Teie arvuti kell on praegu seatud kuupäevale <ph name="CURRENT_DATE" />. Kas see on õige? Kui ei ole, seadke süsteemi kell õigeks ja värskendage lehte.}other{Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />, selle turvasertifikaat aegus # päeva tagasi. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. Teie arvuti kell on praegu seatud kuupäevale <ph name="CURRENT_DATE" />. Kas see on õige? Kui ei ole, seadke süsteemi kell õigeks ja värskendage lehte.}}</translation>
+<translation id="168841957122794586">Serveri sertifikaat sisaldab nõrka krüptograafilist võtit.</translation>
+<translation id="1693754753824026215">Teade veebilehelt aadressil <ph name="SITE" />:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, seadme operatsioonisüsteem ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
<translation id="1821930232296380041">Taotlus või selle parameetrid on kehtetud</translation>
-<translation id="1853748787962613237">Artikli kuvamine ebaõnnestus.</translation>
<translation id="1871208020102129563">Puhverserver on seatud kasutama fikseeritud puhverservereid, mitte pac-skripti URL-i.</translation>
-<translation id="1875753206475436906">heuristiline tüüp: <ph name="HEURISTIC_TYPE"/>
- serveri tüüp: <ph name="SERVER_TYPE"/>
- välja allkiri: <ph name="FIELD_SIGNATURE"/>
- vormi allkiri: <ph name="FORM_SIGNATURE"/>
- katse id: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Avage <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Domeeni <ph name="DOMAIN"/> järjehoidjad</translation>
+<translation id="194030505837763158">Avage <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Domeeni <ph name="DOMAIN" /> järjehoidjad</translation>
<translation id="1973335181906896915">Viga jadaks teisendamisel</translation>
+<translation id="1974060860693918893">Täpsemad</translation>
<translation id="2025186561304664664">Puhverserver seadistatakse automaatselt.</translation>
<translation id="2025623846716345241">Kinnitage uuesti laadimine</translation>
-<translation id="2030481566774242610">Kas mõtlesite aadressi <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Kas mõtlesite aadressi <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Postiindeks</translation>
<translation id="20817612488360358">Kasutamiseks on määratud süsteemi puhverserveri seaded, kuid määratud on ka konkreetne puhverserveri konfigureerimine.</translation>
<translation id="2094505752054353250">Domeeni vastuolu</translation>
<translation id="2096368010154057602">Osakond</translation>
<translation id="2113977810652731515">Kaart</translation>
-<translation id="2114841414352855701">Seda ignoreeritakse, kuna reegel <ph name="POLICY_NAME"/> alistab selle.</translation>
+<translation id="2114841414352855701">Seda ignoreeritakse, kuna reegel <ph name="POLICY_NAME" /> alistab selle.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Mobiili järjehoidjad</translation>
+<translation id="2171101176734966184">Püüdsite jõuda saidile <ph name="DOMAIN" />, kuid server esitas sertifikaadi, mis on allkirjastatud nõrga allkirjaalgoritmiga. See tähendab, et serveri esitatud turvamandaadid võivad olla võltsitud ning server ei pruugi olla see, mida eeldate (võimalik, et suhtlete ründajaga).</translation>
<translation id="2181821976797666341">Reeglid</translation>
<translation id="2212735316055980242">Reeglit ei leitud</translation>
<translation id="2213606439339815911">Kirjete toomine ...</translation>
<translation id="225207911366869382">Väärtus on eeskirjade jaoks aegunud.</translation>
<translation id="2262243747453050782">HTTP viga</translation>
-<translation id="2270192940992995399">Artiklit ei leitud.</translation>
-<translation id="2328300916057834155">Ignoreeriti vale järjehoidjat registris <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Kättesaamatud katsetused</translation>
+<translation id="229702904922032456">Juur- või kesktaseme sertifikaat on aegunud.</translation>
+<translation id="2328300916057834155">Ignoreeriti vale järjehoidjat registris <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Muud järjehoidjad</translation>
<translation id="2359808026110333948">Jätka</translation>
<translation id="2367567093518048410">Tase</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="2396249848217231973">&amp;Võta kustutamine tagasi</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="2455981314101692989">See veebileht on keelanud automaatse täitmise selle vormi puhul.</translation>
<translation id="2479410451996844060">Kehtetu otsingu URL.</translation>
+<translation id="2491120439723279231">Serveri sertifikaat sisaldab vigu.</translation>
<translation id="2495083838625180221">JSON-i parser</translation>
<translation id="2498091847651709837">Uue kaardi skannimine</translation>
<translation id="2556876185419854533">&amp;Võta muudatus tagasi</translation>
-<translation id="2581221116934462656">Kas soovite, et rakendus <ph name="PRODUCT_NAME"/> pakub järgmisel korral sellel saidil <ph name="LANGUAGE_NAME"/> keeles lehtede tõlkimise võimalust?</translation>
+<translation id="2581221116934462656">Kas soovite, et rakendus <ph name="PRODUCT_NAME" /> pakub järgmisel korral sellel saidil <ph name="LANGUAGE_NAME" /> keeles lehtede tõlkimise võimalust?</translation>
<translation id="2587841377698384444">Kataloogi API ID:</translation>
<translation id="2597378329261239068">Dokument on parooliga kaitstud. Sisestage parool.</translation>
+<translation id="2625385379895617796">Teie kell on ees</translation>
<translation id="2639739919103226564">Olek:</translation>
+<translation id="2653659639078652383">Esita</translation>
<translation id="2704283930420550640">Väärtus ei vasta vormingule.</translation>
<translation id="2721148159707890343">Taotlus õnnestus</translation>
+<translation id="2728127805433021124">Serveri sertifikaat on allkirjastatud nõrga allkirjaalgoritmiga.</translation>
<translation id="2774256287122201187">Võite jätkata. Kui liigute edasi lehele, ei ilmu see hoiatus järgmise viie minuti jooksul uuesti.</translation>
<translation id="277499241957683684">Seadme kirje puudub</translation>
<translation id="2835170189407361413">Tühjenda vorm</translation>
-<translation id="2855922900409897335">Kaardi <ph name="CREDIT_CARD"/> kinnitamine</translation>
+<translation id="2855922900409897335">Kaardi <ph name="CREDIT_CARD" /> kinnitamine</translation>
+<translation id="2915500479781995473">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />; selle turvasertifikaat on aegunud. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse. Teie arvuti kell on praegu <ph name="CURRENT_TIME" />. Kas see on õige? Kui see pole õige, korrigeerige süsteemi kellaaega ja värskendage lehte.</translation>
+<translation id="2922350208395188000">Serveri sertifikaati ei saa kontrollida.</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="2958431318199492670">Võrgu seadistus ei vasta ONC standardile. On võimalik, et seadistuse mõnd osa ei saa importida.</translation>
<translation id="2972581237482394796">&amp;Tee uuesti</translation>
-<translation id="3010559122411665027">Loendi kirje „<ph name="ENTRY_INDEX"/>”: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Loendi kirje „<ph name="ENTRY_INDEX" />”: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Reegli tüüp on vale</translation>
<translation id="3105172416063519923">Vara ID:</translation>
<translation id="3145945101586104090">Vastuse dekodeerimine ebaõnnestus</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Saar</translation>
<translation id="3219579145727097045">Sisestage aegumiskuupäev ja 4-kohaline CVC kaardi tagaküljelt</translation>
-<translation id="3228969707346345236">Tõlkimine nurjus, kuna lehe keel on juba <ph name="LANGUAGE"/>.</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="3228969707346345236">Tõlkimine nurjus, kuna lehe keel on juba <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Võta korrastamine tagasi</translation>
+<translation id="3286538390144397061">Taaskäivitada kohe</translation>
<translation id="333371639341676808">Keela sellel leheküljel lisadialoogide loomine.</translation>
-<translation id="3369366829301677151">Krediitkaardi <ph name="CREDIT_CARD"/> värskendamine ja kinnitamine</translation>
+<translation id="3340978935015468852">seaded</translation>
+<translation id="3369192424181595722">Kella viga</translation>
+<translation id="3369366829301677151">Krediitkaardi <ph name="CREDIT_CARD" /> värskendamine ja kinnitamine</translation>
<translation id="337363190475750230">Eraldatud</translation>
<translation id="3377188786107721145">Viga reegli sõelumisel</translation>
<translation id="3380365263193509176">Tundmatu viga</translation>
<translation id="3380864720620200369">Kliendi ID:</translation>
<translation id="3427342743765426898">&amp;Muuda uuesti</translation>
+<translation id="3435896845095436175">Luba</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Hankimise intervall:</translation>
+<translation id="3462200631372590220">Peida täpsemad üksikasjad</translation>
+<translation id="3528171143076753409">Serveri sertifikaat ei ole usaldusväärne.</translation>
<translation id="3542684924769048008">Kasuta parooli:</translation>
<translation id="3583757800736429874">&amp;Teisalda uuesti</translation>
<translation id="3623476034248543066">Kuva väärtused</translation>
+<translation id="3648607100222897006">Need eksperimentaalsed funktsioonid võivad igal ajal muutuda, rikki minna või kaduda. Me ei anna mingeid garantiisid selle kohta, mis juhtub, kui mõne eksperimendi sisse lülitate. Võimalik on teie brauseri iseeneslik süttimine. Kui tõsiselt rääkida, siis võib brauser kustutada kõik teie andmed või ootamatul viisil võidakse rikkuda teie turvalisust ja privaatsust. Kõik eksperimendid, mis te brauseris lubate, lubatakse brauseri kõigile kasutajatele. Jätkake ettevaatlikult.</translation>
<translation id="3650584904733503804">Valideerimine õnnestus</translation>
<translation id="370665806235115550">Laadimine...</translation>
<translation id="3712624925041724820">Litsentsid on ammendunud</translation>
<translation id="3739623965217189342">Teie kopeeritud link</translation>
<translation id="375403751935624634">Tõlkimine ebaõnnestus serverivea tõttu.</translation>
<translation id="385051799172605136">Tagasi</translation>
+<translation id="3858027520442213535">Värskenda kuupäeva ja kellaaega</translation>
<translation id="3884278016824448484">Seadme identifikaator on konfliktne</translation>
<translation id="3885155851504623709">Vald</translation>
<translation id="3934680773876859118">PDF-dokumendi laadimine nurjus</translation>
<translation id="3963721102035795474">Lugejarežiim</translation>
<translation id="4030383055268325496">&amp;Võta lisamine tagasi</translation>
-<translation id="4058922952496707368">Võti „<ph name="SUBKEY"/>”: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">HOIATUS</translation>
+<translation id="4058922952496707368">Võti „<ph name="SUBKEY" />”: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Puhverserveri konfigureerimine on määratud kasutama pac-skripti URL-i, mitte fikseeritud puhverservereid.</translation>
<translation id="409504436206021213">Ära laadi uuesti</translation>
<translation id="4103249731201008433">Seadme seerianumber on kehtetu</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Sobimatu allkiri</translation>
<translation id="4269787794583293679">(Kasutajanimi puudub)</translation>
<translation id="4300246636397505754">Vanema soovitused</translation>
-<translation id="4372948949327679948">Oodatud väärtus: <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Artiklit ei leitud</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="4394049700291259645">Keela</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="443673843213245140">Puhverserveri kasutamine on keelatud, kuid määratud on ka konkreetne puhverserveri konfigureerimine.</translation>
-<translation id="4506176782989081258">Valideerimisviga: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Valideerimisviga: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Kas eemaldada Chrome'ist aadress?</translation>
<translation id="4594403342090139922">&amp;Võta kustutamine tagasi</translation>
<translation id="4607653538520819196">Andmemahu säästja ei saa seda lehte puhverdada.</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="4726672564094551039">Laadi reeglid uuesti</translation>
+<translation id="4728558894243024398">Platvorm</translation>
+<translation id="4771973620359291008">Tekkis tundmatu viga.</translation>
<translation id="4800132727771399293">Kontrollige aegumiskuupäeva ja CVC-d ning proovige uuesti</translation>
<translation id="4813512666221746211">Võrgu viga</translation>
+<translation id="4816492930507672669">Sobita lehele</translation>
<translation id="4850886885716139402">Kuva</translation>
-<translation id="4923417429809017348">Leht on tõlgitud teadmata keelest <ph name="LANGUAGE_LANGUAGE"/> keelde</translation>
+<translation id="4923417429809017348">Leht on tõlgitud teadmata keelest <ph name="LANGUAGE_LANGUAGE" /> keelde</translation>
<translation id="4926049483395192435">Tuleb määrata.</translation>
<translation id="4968547170521245791">Puhverserverit ei saa kasutada</translation>
-<translation id="498957508165411911">Kas tõlkida <ph name="ORIGINAL_LANGUAGE"/> keelest <ph name="TARGET_LANGUAGE"/> keelde?</translation>
+<translation id="498957508165411911">Kas tõlkida <ph name="ORIGINAL_LANGUAGE" /> keelest <ph name="TARGET_LANGUAGE" /> keelde?</translation>
<translation id="5019198164206649151">Varusalves esineb probleeme</translation>
<translation id="5031870354684148875">Teave Google'i tõlke kohta</translation>
+<translation id="5045550434625856497">Vale parool</translation>
+<translation id="5087286274860437796">Serveri sertifikaat pole praegu kehtiv.</translation>
<translation id="5089810972385038852">Osariik</translation>
+<translation id="5094747076828555589">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, Chromium ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
<translation id="5095208057601539847">Provints</translation>
<translation id="5145883236150621069">Reegli vastuses sisaldus veakood</translation>
<translation id="5172758083709347301">Masin</translation>
-<translation id="5179510805599951267">Tegu ei ole <ph name="ORIGINAL_LANGUAGE"/> keelega? Andke veast teada</translation>
+<translation id="5179510805599951267">Tegu ei ole <ph name="ORIGINAL_LANGUAGE" /> keelega? Andke veast teada</translation>
<translation id="5190835502935405962">Järjehoidjariba</translation>
+<translation id="5199729219167945352">Katsed</translation>
+<translation id="5251803541071282808">Pilv</translation>
<translation id="5295309862264981122">Kinnita navigatsiooni</translation>
<translation id="5299298092464848405">Reegli sõelumisel ilmnes viga</translation>
+<translation id="5316812925700871227">Pööra vastupäeva</translation>
<translation id="5317780077021120954">Salvesta</translation>
<translation id="536296301121032821">Reegli seadete talletamine ebaõnnestus</translation>
-<translation id="5439770059721715174">Skeemi valideerimise viga asukohas „<ph name="ERROR_PATH"/>”: <ph name="ERROR"/></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="5439770059721715174">Skeemi valideerimise viga asukohas „<ph name="ERROR_PATH" />”: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Reegli ajatempel on sobimatu</translation>
<translation id="5470861586879999274">&amp;Muuda uuesti</translation>
<translation id="5509780412636533143">Hallatud järjehoidjad</translation>
<translation id="5523118979700054094">Reegli nimi</translation>
<translation id="552553974213252141">Kas tekst ekstraktiti õigesti?</translation>
<translation id="5540224163453853">Taotletud artiklit ei õnnestunud leida.</translation>
+<translation id="5556459405103347317">Laadi uuesti</translation>
<translation id="5565735124758917034">Aktiivne</translation>
<translation id="560412284261940334">Haldust ei toetata</translation>
<translation id="5629630648637658800">Reegli seadete laadimine ebaõnnestus</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Praegune kasutaja</translation>
<translation id="5813119285467412249">&amp;Lisa uuesti</translation>
<translation id="5872918882028971132">Vanema soovitused</translation>
-<translation id="587701087903783706">Sule mobiilisõbralik vaade</translation>
<translation id="59107663811261420">Google Payments ei toeta selle kaupmehe puhul seda tüüpi kaarti. Valige teine kaart.</translation>
+<translation id="5975083100439434680">Suumib välja</translation>
<translation id="5989320800837274978">Määratud ei ole fikseeritud puhverservereid ega pac-skriptiga URL-i.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Sule</translation>
+<translation id="6060685159320643512">Ettevaatust, need katsed võivad hammustada.</translation>
+<translation id="6151417162996330722">Serveri sertifikaadi kehtivusaeg on liiga pikk.</translation>
<translation id="6154808779448689242">Tagastatud reegli luba ei kattu praeguse loaga</translation>
<translation id="6165508094623778733">Lisateave</translation>
<translation id="6259156558325130047">&amp;Korrasta uuesti</translation>
-<translation id="6263376278284652872">Domeeni <ph name="DOMAIN"/> järjehoidjad</translation>
+<translation id="6263376278284652872">Domeeni <ph name="DOMAIN" /> järjehoidjad</translation>
<translation id="6282194474023008486">Sihtnumber</translation>
<translation id="6337534724793800597">Reeglite filtreerimine nime järgi</translation>
+<translation id="6387478394221739770">Kas olete huvitatud Chrome'i uutest lahedatest funktsioonidest? Proovige meie beetakanalit aadressil chrome.com/beta.</translation>
+<translation id="6426993025560594914">Teie platvormil on saadaval kõik katseversioonid.</translation>
<translation id="6445051938772793705">Riik</translation>
<translation id="6458467102616083041">Seda eiratakse, kuna vaikeotsing on reegliga keelatud.</translation>
<translation id="647261751007945333">Seadme reeglid</translation>
<translation id="6512448926095770873">Lahku sellelt leheküljelt</translation>
<translation id="6529602333819889595">&amp;Kustuta uuesti</translation>
<translation id="6550675742724504774">Valikud</translation>
-<translation id="6597614308054261376">Soovite pääseda lehele <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Andmemahu säästja ei saa seda lehte praegu puhverdada.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/>'i otsing</translation>
+<translation id="6597614308054261376">Soovite pääseda lehele <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Andmemahu säästja ei saa seda lehte praegu puhverdada.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" />'i otsing</translation>
<translation id="6644283850729428850">See reegel on aegunud.</translation>
<translation id="6646897916597483132">Sisestage 4-kohaline CVC kaardi tagaküljelt</translation>
+<translation id="674375294223700098">Serveri sertifikaadi tundmatu viga.</translation>
<translation id="6753269504797312559">Reegli väärtus</translation>
<translation id="6831043979455480757">Tõlgi</translation>
<translation id="6839929833149231406">Piirkond</translation>
<translation id="6874604403660855544">&amp;Lisa uuesti</translation>
<translation id="6891596781022320156">Reegli taset ei toetata.</translation>
<translation id="6915804003454593391">Kasutaja:</translation>
+<translation id="6957887021205513506">Serveri sertifikaat näib olevat võltsing.</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6965978654500191972">Seade</translation>
<translation id="6970216967273061347">Ringkond</translation>
<translation id="6973656660372572881">Määratud on nii fikseeritud puhverserverid kui ka pac-skriptiga URL.</translation>
<translation id="6980028882292583085">JavaScripti märguanne</translation>
<translation id="7012363358306927923">Hiina UnionPay</translation>
+<translation id="7050187094878475250">Üritasite jõuda domeenile <ph name="DOMAIN" />, kuid server esitas sertifikaadi, mille kehtivusaeg on liiga pikk, et olla usaldusväärne.</translation>
<translation id="7087282848513945231">Maakond</translation>
-<translation id="7108649287766967076">Tõlkimine <ph name="TARGET_LANGUAGE"/> keelde ebaõnnestus.</translation>
+<translation id="7108649287766967076">Tõlkimine <ph name="TARGET_LANGUAGE" /> keelde ebaõnnestus.</translation>
<translation id="7139724024395191329">Emiraat</translation>
+<translation id="7179921470347911571">Taaskäivita kohe</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="7186367841673660872">See leht on tõlgitud keelest<ph name="ORIGINAL_LANGUAGE" />keelde<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Otsi <ph name="SITE_NAME"/>-st päringut <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Otsi <ph name="SITE_NAME" />-st päringut <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Privaatset ühendust ei saa domeeniga <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> luua, kuna arvuti kuupäev ja kellaaeg (<ph name="DATE_AND_TIME" />) on valed.</translation>
<translation id="7275334191706090484">Hallatud järjehoidjad</translation>
<translation id="7298195798382681320">Soovitatud</translation>
<translation id="7334320624316649418">&amp;Korrasta uuesti</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">Javascript</translation>
<translation id="7537536606612762813">Kohustuslik</translation>
<translation id="7542995811387359312">Automaatne krediitkaardi täide on keelatud, sest see vorm ei kasuta turvalist ühendust.</translation>
-<translation id="7568593326407688803">See leht on keeles<ph name="ORIGINAL_LANGUAGE"/>Kas soovite seda tõlkida?</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="7568593326407688803">See leht on keeles<ph name="ORIGINAL_LANGUAGE" />Kas soovite seda tõlkida?</translation>
<translation id="7569952961197462199">Kas eemaldada Chrome'ist krediitkaart?</translation>
-<translation id="7600965453749440009">Ära kunagi tõlgi: <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Väärtus on vahemikust (<ph name="VALUE"/>) väljaspool.</translation>
+<translation id="7592362899630581445">Serveri sertifikaat rikub nime piiranguid.</translation>
+<translation id="7600965453749440009">Ära kunagi tõlgi: <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Väärtus on vahemikust (<ph name="VALUE" />) väljaspool.</translation>
+<translation id="7674629440242451245">Kas olete huvitatud Chrome'i uutest lahedatest funktsioonidest? Proovige meie arenduskanalit aadressil chrome.com/beta.</translation>
<translation id="7752995774971033316">Haldamata</translation>
+<translation id="7761701407923456692">Serveri sertifikaat ei vasta URL-ile.</translation>
<translation id="777702478322588152">Prefektuur</translation>
<translation id="7791543448312431591">Lisa</translation>
<translation id="7805768142964895445">Olek</translation>
<translation id="7813600968533626083">Kas eemaldada Chrome'ist vormi soovitus?</translation>
<translation id="7887683347370398519">Kontrollige CVC-d ja proovige uuesti</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Serveri sertifikaat ei kehti veel.</translation>
<translation id="7956713633345437162">Mobiili järjehoidjad</translation>
<translation id="7961015016161918242">Mitte kunagi</translation>
<translation id="7977590112176369853">&lt;sisesta päring&gt;</translation>
-<translation id="7983301409776629893">Tõlgi alati keelest <ph name="ORIGINAL_LANGUAGE"/> keelde <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Tõlgi alati keelest <ph name="ORIGINAL_LANGUAGE" /> keelde <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Töölaua järjehoidjad</translation>
<translation id="7995512525968007366">Ei ole määratud</translation>
-<translation id="8034522405403831421">Leht on <ph name="SOURCE_LANGUAGE"/> keeles. Kas tõlkida <ph name="TARGET_LANGUAGE"/> keelde?</translation>
+<translation id="8003882219468422867">Ettevõtte alistamine</translation>
+<translation id="8034522405403831421">Leht on <ph name="SOURCE_LANGUAGE" /> keeles. Kas tõlkida <ph name="TARGET_LANGUAGE" /> keelde?</translation>
<translation id="8088680233425245692">Artikli kuvamine ebaõnnestus.</translation>
<translation id="8091372947890762290">Aktiveerimine on serveris ootel</translation>
<translation id="8194797478851900357">&amp;Võta teisaldamine tagasi</translation>
-<translation id="8201077131113104583">ID-ga „<ph name="EXTENSION_ID"/>” laienduse kehtetu värskendamise URL.</translation>
+<translation id="8201077131113104583">ID-ga „<ph name="EXTENSION_ID" />” laienduse kehtetu värskendamise URL.</translation>
<translation id="8208216423136871611">Ära salvesta</translation>
<translation id="8218327578424803826">Määratud asukoht:</translation>
<translation id="8249320324621329438">Viimati toodud:</translation>
+<translation id="8294431847097064396">Allikas</translation>
<translation id="8308427013383895095">Tõlkimine ebaõnnestus võrguühenduse probleemi tõttu.</translation>
<translation id="8311778656528046050">Kas soovite kindlasti lehe uuesti laadida?</translation>
<translation id="8349305172487531364">Järjehoidjariba</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Kehtib:</translation>
<translation id="8530504477309582336">Google Payments ei toeta seda tüüpi kaarti. Valige teine kaart.</translation>
<translation id="8553075262323480129">Tõlkimine nurjus, kuna lehe keelt ei õnnestunud määrata.</translation>
-<translation id="8571890674111243710">Lehe tõlkimine <ph name="LANGUAGE"/> keelde...</translation>
+<translation id="8559762987265718583">Privaatset ühendust ei saa domeeniga <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> luua, kuna seadme kuupäev ja kellaaeg (<ph name="DATE_AND_TIME" />) on valed.</translation>
+<translation id="8571890674111243710">Lehe tõlkimine <ph name="LANGUAGE" /> keelde...</translation>
+<translation id="8647750283161643317">Lähtesta kõik vaikeolekusse</translation>
<translation id="8713130696108419660">Sobimatu esialgne allkiri</translation>
<translation id="8725066075913043281">Proovi uuesti</translation>
+<translation id="8738058698779197622">Turvalise ühenduse loomiseks peab kell olema õigesti seadistatud. See on nii, kuna sertifikaadid, mida veebisaidid kasutavad enda tuvastamiseks, kehtivad ainult teatud perioodi jooksul. Kuna teie seadme kell on vale, ei saa Chromium neid sertifikaate kinnitada.</translation>
<translation id="8790007591277257123">&amp;Kustuta uuesti</translation>
<translation id="8804164990146287819">Privaatsuseeskirjad</translation>
+<translation id="8820817407110198400">Järjehoidjad</translation>
<translation id="8824019021993735287">Chrome ei saanud praegu teie kaarti kinnitada. Proovige hiljem uuesti.</translation>
<translation id="8834246243508017242">Luba automaatne täitmine kontakte kasutades …</translation>
<translation id="883848425547221593">Muud järjehoidjad</translation>
+<translation id="884923133447025588">Tühistusmehhanismi ei leitud.</translation>
<translation id="8866481888320382733">Reegli seadete sõelumisel ilmnes viga</translation>
<translation id="8876793034577346603">Võrgu seadistust ei õnnestunud sõeluda.</translation>
<translation id="8891727572606052622">Kehtetu puhverserveri režiim.</translation>
-<translation id="8940229512486821554">Käita teenuse <ph name="EXTENSION_NAME"/> käsku: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Kahjuks ei ole see eksperiment teie platvormil saadaval.</translation>
+<translation id="8903921497873541725">Suurendab</translation>
+<translation id="8932102934695377596">Teie kell on taga</translation>
+<translation id="8940229512486821554">Käita teenuse <ph name="EXTENSION_NAME" /> käsku: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Serveri sertifikaat on aegunud.</translation>
<translation id="8988760548304185580">Sisestage aegumiskuupäev ja 3-kohaline CVC kaardi tagaküljelt</translation>
-<translation id="9020542370529661692">See leht on tõlgitud <ph name="TARGET_LANGUAGE"/> keelde</translation>
+<translation id="901974403500617787">Kogu süsteemis kehtivaid märgiseid saab määrata ainult omanik: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">See leht on tõlgitud <ph name="TARGET_LANGUAGE" /> keelde</translation>
+<translation id="9049981332609050619">Proovisite jõuda domeenile <ph name="DOMAIN" />, kuid server esitas kehtetu sertifikaadi.</translation>
<translation id="9125941078353557812">Sisestage 3-kohaline CVC kaardi tagaküljelt</translation>
<translation id="9137013805542155359">Kuva originaal</translation>
<translation id="9148507642005240123">&amp;Võta muudatus tagasi</translation>
<translation id="9154176715500758432">Jää sellele leheküljele</translation>
<translation id="9170848237812810038">&amp;Võta tagasi</translation>
+<translation id="917450738466192189">Serveri sertifikaat on kehtetu.</translation>
+<translation id="9187827965378254003">Paistab, et praegu pole saadaval ühtegi katsetust.</translation>
<translation id="9207861905230894330">Artikli lisamine ebaõnnestus.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">TÜHJENDA VORM</translation>
+<translation id="988159990683914416">Arendaja järk</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_fa.xtb b/chromium/components/strings/components_strings_fa.xtb
index bb0d3115755..6f5565bd6e9 100644
--- a/chromium/components/strings/components_strings_fa.xtb
+++ b/chromium/components/strings/components_strings_fa.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="fa">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fa">
+<translation id="1032854598605920125">چرخش در جهت عقربه‌های ساعت</translation>
<translation id="1055184225775184556">&amp;واگرد افزودن</translation>
<translation id="106701514854093668">نشانک‌های دسک‌تاپ</translation>
-<translation id="1103523840287552314"><ph name="LANGUAGE"/> همیشه ترجمه شود</translation>
+<translation id="1080116354587839789">متناسب با پهنا</translation>
+<translation id="1103523840287552314"><ph name="LANGUAGE" /> همیشه ترجمه شود</translation>
<translation id="1113869188872983271">&amp;واگرد ترتیب‌بندی مجدد</translation>
<translation id="111844081046043029">آیا می‌خواهید این صفحه را ترک کنید؟</translation>
<translation id="112840717907525620">حافظه پنهان خط‌مشی مورد تأیید است</translation>
<translation id="1132774398110320017">‏تنظیمات تکمیل خودکار Chrome...</translation>
-<translation id="1152921474424827756">دسترسی به یک <ph name="BEGIN_LINK"/>نسخه ذخیره شده در حافظه پنهان<ph name="END_LINK"/> از <ph name="URL"/></translation>
+<translation id="1150979032973867961">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن مورد اعتماد سیستم عامل رایانه شما نیست. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
+<translation id="1152921474424827756">دسترسی به یک <ph name="BEGIN_LINK" />نسخه ذخیره شده در حافظه پنهان<ph name="END_LINK" /> از <ph name="URL" /></translation>
+<translation id="121201262018556460">شما می‌خواستید به <ph name="DOMAIN" /> دسترسی یابید، اما سرور یک گواهی دارای کلید ضعیف ارائه داد. یک مهاجم ممکن است کلید خصوصی را تخریب کرده باشد و سرور، همان سروری نباشد که شما انتظار داشتید (ممکن است در حال ارتباط با یک مهاجم باشید).</translation>
<translation id="1227224963052638717">خط‌مشی ناشناخته.</translation>
<translation id="1227633850867390598">پنهان کردن مقدار</translation>
<translation id="1228893227497259893">‏شناسه entity نادرست</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">دامنه ثبت‌نام:</translation>
<translation id="1344588688991793829">‏تنظیمات تکمیل خودکار Chromium...</translation>
<translation id="1426410128494586442">بله</translation>
+<translation id="1430915738399379752">چاپ</translation>
<translation id="1455235771979731432">هنگام تأیید کارت‌تان مشکلی رخ داد. اتصال اینترنت را بررسی کرده و دوباره امتحان کنید.</translation>
<translation id="1491151370853475546">تازه‌سازی این صفحه</translation>
<translation id="1549470594296187301">برای استفاده از این قابلیت، جاوا اسکریپت باید فعال باشد.</translation>
-<translation id="1639239467298939599">بارگیری</translation>
<translation id="1640180200866533862">خط‌مشی‌های کاربر</translation>
<translation id="1644184664548287040">پیکربندی شبکه نامعتبر است و نتوانست وارد شود.</translation>
-<translation id="1693754753824026215">صفحه <ph name="SITE"/> نشان می‌دهد:</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="168841957122794586">گواهی‌نامه سرور دارای یک کلید رمزنگاری ضعیف است.</translation>
+<translation id="1693754753824026215">صفحه <ph name="SITE" /> نشان می‌دهد:</translation>
+<translation id="1706954506755087368">{1,plural, =1{این سرور نتوانست ثابت کند این <ph name="DOMAIN" /> است؛ اعتبار گواهی امنیتی آن ظاهراً فردا شروع می‌شود. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند.}one{این سرور نتوانست ثابت کند این <ph name="DOMAIN" /> است؛ اعتبار گواهی امنیتی آن ظاهراً # روز دیگر شروع می‌شود. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند.}other{این سرور نتوانست ثابت کند این <ph name="DOMAIN" /> است؛ اعتبار گواهی امنیتی آن ظاهراً # روز دیگر شروع می‌شود. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن مورد اعتماد سیستم عامل دستگاه شما نیست. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
<translation id="1821930232296380041">پارامترهای درخواست یا درخواست نامعتبر</translation>
-<translation id="1853748787962613237">نمایش مقاله ناموفق بود.</translation>
<translation id="1871208020102129563">‏تنظیم پروکسی به گونه‌ای است که از سرورهای ثابت پروکسی استفاده کند و از آدرس اسکریپت pac. استفاده نکند.</translation>
-<translation id="1875753206475436906">نوع غیرمستدل: <ph name="HEURISTIC_TYPE"/>
- نوع سرور: <ph name="SERVER_TYPE"/>
- امضای فیلد: <ph name="FIELD_SIGNATURE"/>
- امضای فرم: <ph name="FORM_SIGNATURE"/>
- شناسه آزمایش: «<ph name="EXPERIMENT_ID"/>»</translation>
-<translation id="194030505837763158">رفتن به <ph name="LINK"/></translation>
-<translation id="1962204205936693436">نشانک‌های <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">رفتن به <ph name="LINK" /></translation>
+<translation id="1962204205936693436">نشانک‌های <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">خطای ترتیب</translation>
+<translation id="1974060860693918893">پیشرفته</translation>
<translation id="2025186561304664664">پروکسی بر روی پیکربندی خودکار تنظیم شده است.</translation>
<translation id="2025623846716345241">تأیید تازه‌سازی</translation>
-<translation id="2030481566774242610">منظورتان <ph name="LINK"/> بود؟</translation>
+<translation id="2030481566774242610">منظورتان <ph name="LINK" /> بود؟</translation>
<translation id="2053553514270667976">کد پستی</translation>
<translation id="20817612488360358">تنظیمات پروکسی سیستم تنظیم شده تا مورد استفاده قرار گیرد، اما یک پیکربندی مشخص برای پروکسی نیز تعیین شده است.</translation>
<translation id="2094505752054353250">عدم تطابق دامنه</translation>
<translation id="2096368010154057602">حوزه</translation>
<translation id="2113977810652731515">کارت</translation>
-<translation id="2114841414352855701">نادیده گرفته شد زیرا <ph name="POLICY_NAME"/> آن را لغو می‌کند.</translation>
+<translation id="2114841414352855701">نادیده گرفته شد زیرا <ph name="POLICY_NAME" /> آن را لغو می‌کند.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">نشانک‌های تلفن‌ همراه</translation>
+<translation id="2171101176734966184">شما سعی داشتید به <ph name="DOMAIN" /> دسترسی داشته باشید، اما گواهی ارائه شده از سوی سرور با استفاده از یک الگوریتم امضای ضعیف امضا شده است. یعنی ممکن است اطلاعات کاربری امنیتی ارائه شده از سوی سرور ساختگی باشد و ممکن است این سرور سروی نباشد که شما می‌خواستید (ممکن است شما با یک مهاجم در ارتباط باشید).</translation>
<translation id="2181821976797666341">خط‌ مشی‌ها</translation>
<translation id="2212735316055980242">خط‌مشی یافت نشد</translation>
<translation id="2213606439339815911">در حال واکشی موارد...</translation>
<translation id="225207911366869382">این مقدار برای این خط‌مشی منسوخ شده است؟</translation>
<translation id="2262243747453050782">‏خطای HTTP</translation>
-<translation id="2270192940992995399">مقاله یافت نشد.</translation>
-<translation id="2328300916057834155">نشانک نامعتبر در نمایه <ph name="ENTRY_INDEX"/> نادیده گرفته شد</translation>
+<translation id="2282872951544483773">آزمایش‌های غیرقابل دسترس</translation>
+<translation id="229702904922032456">گواهینامه واسط یا ریشه منقضی شده است.</translation>
+<translation id="2328300916057834155">نشانک نامعتبر در نمایه <ph name="ENTRY_INDEX" /> نادیده گرفته شد</translation>
<translation id="2354001756790975382">نشانک‌های دیگر</translation>
<translation id="2359808026110333948">ادامه</translation>
<translation id="2367567093518048410">سطح</translation>
+<translation id="2384307209577226199">پیش‌فرض شرکتی</translation>
+<translation id="2386255080630008482">گواهی سرور باطل شده است.</translation>
<translation id="2392959068659972793">نمایش خط‌مشی‌ها با مقدار تنظیم نشده</translation>
<translation id="2396249848217231973">&amp;واگرد حذف</translation>
+<translation id="2413528052993050574">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ ممکن است گواهی امنیتی آن باطل شده باشد. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
<translation id="2455981314101692989">این صفحهٔ وب، تکمیل خودکار این فرم را غیر فعال کرده است.</translation>
<translation id="2479410451996844060">‏URL جستجو نامعتبر است.</translation>
+<translation id="2491120439723279231">گواهی سرور دارای چندین خطاست.</translation>
<translation id="2495083838625180221">‏تجزیه‌کننده JSON</translation>
<translation id="2498091847651709837">اسکن کارت جدید</translation>
<translation id="2556876185419854533">&amp;واگرد ویرایش</translation>
-<translation id="2581221116934462656">مایلید دفعه بعد <ph name="PRODUCT_NAME"/> پیشنهاد دهد صفحه‌های <ph name="LANGUAGE_NAME"/> از این سایت ترجمه شوند؟</translation>
+<translation id="2581221116934462656">مایلید دفعه بعد <ph name="PRODUCT_NAME" /> پیشنهاد دهد صفحه‌های <ph name="LANGUAGE_NAME" /> از این سایت ترجمه شوند؟</translation>
<translation id="2587841377698384444">‏شناسه Directory API:</translation>
-<translation id="2597378329261239068">این سند توسط رمز ورود محافظت می‌شود. لطفاً یک رمز ورود وارد کنید.</translation>
+<translation id="2597378329261239068">این سند توسط گذرواژه محافظت می‌شود. لطفاً یک گذرواژه وارد کنید.</translation>
+<translation id="2625385379895617796">ساعت شما جلو است</translation>
<translation id="2639739919103226564">وضعیت:</translation>
+<translation id="2653659639078652383">ارائه</translation>
<translation id="2704283930420550640">مقدار با فرمت مطابقت ندارد.</translation>
<translation id="2721148159707890343">درخواست با موفقیت انجام شد</translation>
+<translation id="2728127805433021124">گواهی سرور با استفاده از یک الگوریتم امضای ضعیف امضا شده است.</translation>
<translation id="2774256287122201187">می‌توانید ادامه دهید. اگر رفتن به صفحه را ادامه دهید، این هشدار به مدت پنج دقیقه دوباره ظاهر نمی‌شود.</translation>
<translation id="277499241957683684">ثبت دستگاه موجود نیست</translation>
<translation id="2835170189407361413">پاک کردن فرم</translation>
-<translation id="2855922900409897335"><ph name="CREDIT_CARD"/> را تأیید کنید</translation>
+<translation id="2855922900409897335"><ph name="CREDIT_CARD" /> را تأیید کنید</translation>
+<translation id="2915500479781995473">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهینامه امنیتی آن منقضی شده است. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است. در حال حاضر ساعت رایانه‌تان روی <ph name="CURRENT_TIME" /> تنظیم شده است. آیا این زمان درست است؟ اگر درست نیست، باید ساعت سیستم‌تان را تنظیم کنید و سپس این صفحه را بازخوانی نمایید.</translation>
+<translation id="2922350208395188000">گواهی سرور بررسی نمی‌شود.</translation>
+<translation id="2941952326391522266">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن از <ph name="DOMAIN2" /> است. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
<translation id="2958431318199492670">‏پیکربندی شبکه با استاندارد ONC تطابق ندارد. بخشی از پیکربندی ممکن است وارد نشود.</translation>
<translation id="2972581237482394796">انجام مجدد</translation>
-<translation id="3010559122411665027">ورودی لیست &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">ورودی لیست "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">نوع خط‌مشی اشتباه است</translation>
<translation id="3105172416063519923">شناسه دارایی:</translation>
<translation id="3145945101586104090">رمزگشایی پاسخ انجام نشد</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">کشف کردن</translation>
<translation id="3174168572213147020">جزیره</translation>
<translation id="3219579145727097045">‏تاریخ انقضا و کد تأیید چهار رقمی CVC را از پشت کارت‌تان وارد کنید</translation>
-<translation id="3228969707346345236">ترجمه انجام نشد زیرا صفحه در حال حاضر به زبان <ph name="LANGUAGE"/> است.</translation>
+<translation id="3225919329040284222">سرور گواهی را نشان می‌دهد که با موارد پیش‌بینی‌شده داخلی مطابقت ندارد. این پیش‌بینی‌ها به‌طور حتم وب‌سایتهای دارای امنیت بالا را جهت محافظت از شما در بر می‌گیرند.</translation>
+<translation id="3228969707346345236">ترجمه انجام نشد زیرا صفحه در حال حاضر به زبان <ph name="LANGUAGE" /> است.</translation>
<translation id="3270847123878663523">&amp;واگرد ترتیب‌بندی مجدد</translation>
+<translation id="3286538390144397061">راه‌اندازی مجدد اکنون</translation>
<translation id="333371639341676808">از ایجاد کادرهای گفتگوی دیگر توسط این صفحه جلوگیری شود.</translation>
-<translation id="3369366829301677151"><ph name="CREDIT_CARD"/> را به‌روزرسانی و تأیید کنید</translation>
+<translation id="3340978935015468852">تنظیمات</translation>
+<translation id="3369192424181595722">خطای ساعت</translation>
+<translation id="3369366829301677151"><ph name="CREDIT_CARD" /> را به‌روزرسانی و تأیید کنید</translation>
<translation id="337363190475750230">لغو مجوز شد</translation>
<translation id="3377188786107721145">خطای تجزیه خط‌مشی</translation>
<translation id="3380365263193509176">خطای ناشناخته</translation>
<translation id="3380864720620200369">شناسه سرویس‌گیرنده:</translation>
<translation id="3427342743765426898">&amp;انجام مجدد ویرایش</translation>
+<translation id="3435896845095436175">فعال کردن</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">فاصله زمانی واکشی:</translation>
+<translation id="3462200631372590220">پنهان کردن پیشرفته</translation>
+<translation id="3528171143076753409">گواهی سرور مطمئن نیست.</translation>
<translation id="3542684924769048008">استفاده از گذرواژه برای:</translation>
<translation id="3583757800736429874">&amp;انجام مجدد انتقال</translation>
<translation id="3623476034248543066">نشان دادن مقدار</translation>
+<translation id="3648607100222897006">این ویژگی‌های آزمایشی ممکن است در هر زمانی تغییر کنند، نقض شوند یا ناپدید شوند. اگر یکی از این ویژگی‌های آزمایشی را فعال کنید ما هیچ تضمینی در مورد آنچه که ممکن است اتفاق بیفتد نداریم، و حتی ممکن است مرورگر شما خود به خود ناپدید شود. در واقع، ممکن است مرورگر شما تمام داده‌های شما را حذف کند یا امنیت و حریم خصوصی شما می‌تواند به صورت غیرمنتظره‌ای به خطر بیفتد. هر ویژگی آزمایشی که فعال می‌کنید برای تمام کاربران این مرورگر فعال خواهد شد. لطفاً با احتیاط ادامه دهید.</translation>
<translation id="3650584904733503804">ارزیابی موفق بود</translation>
<translation id="370665806235115550">در حال بارگیری...</translation>
<translation id="3712624925041724820">مجوزها دیگر معتبر نیستند</translation>
<translation id="3739623965217189342">پیوندی که کپی کرده‌اید</translation>
<translation id="375403751935624634">بدلیل خطای سرور ترجمه انجام نشد.</translation>
<translation id="385051799172605136">بازگشت</translation>
+<translation id="3858027520442213535">به‌روزرسانی تاریخ و زمان</translation>
<translation id="3884278016824448484">شناسه دستگاه یکسان نیست</translation>
<translation id="3885155851504623709">بخش</translation>
<translation id="3934680773876859118">‏بارگیری سند PDF انجام نشد</translation>
<translation id="3963721102035795474">حالت «خواننده»</translation>
<translation id="4030383055268325496">&amp;واگرد افزودن</translation>
-<translation id="4058922952496707368">کلید &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">اخطار</translation>
+<translation id="4058922952496707368">کلید "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">‏تنظیمات پروکسی، برای استفاده از آدرس اسکریپت pac. تنظیم شده است و از سرورهای ثابت نمی‌تواند استفاده کند.</translation>
<translation id="409504436206021213">تازه‌سازی نشود</translation>
<translation id="4103249731201008433">شماره سریال دستگاه نامعتبر است</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">امضای نادرست</translation>
<translation id="4269787794583293679">(بدون نام کاربری)</translation>
<translation id="4300246636397505754">پیشنهادات والدین</translation>
-<translation id="4372948949327679948">مقدار مورد انتظار <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">مقاله یافت نشد.</translation>
+<translation id="4372948949327679948">مقدار مورد انتظار <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">شما سعی در دسترسی به <ph name="DOMAIN" /> را داشتید، اما صادر کننده، گواهی ارائه شده از سوی سرور را باطل کرده است. یعنی اصلاً نباید به اطلاعات کاربری که این سرور ارائه می‌کند اطمینان کرد. ممکن است شما با مهاجمی در ارتباط باشید.</translation>
+<translation id="4394049700291259645">غیر فعال کردن</translation>
+<translation id="4424024547088906515">‏این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن مورد اعتماد Chrome نیست. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
<translation id="443673843213245140">استفاده از پروکسی غیرفعال است اما یک پیکربندی خاص برای پروکسی تعیین شده است.</translation>
-<translation id="4506176782989081258">خطای ارزیابی: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">خطای ارزیابی: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">‏آدرس از Chrome پاک شود؟</translation>
<translation id="4594403342090139922">&amp;واگرد حذف</translation>
<translation id="4607653538520819196">این صفحه نمی‌تواند با «صرفه‌جویی در مصرف داده» پشتیبانی شود.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن خطاهایی دارد. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
<translation id="4726672564094551039">تازه‌سازی خط مشی‌ها</translation>
+<translation id="4728558894243024398">پلت فورم</translation>
+<translation id="4771973620359291008">خطای ناشناخته‌ای رخ داد.</translation>
<translation id="4800132727771399293">‏تاریخ انقضا و CVC را بررسی کرده و دوباره امتحان کنید</translation>
<translation id="4813512666221746211">خطای شبکه</translation>
+<translation id="4816492930507672669">متناسب با صفحه</translation>
<translation id="4850886885716139402">نما</translation>
-<translation id="4923417429809017348">این صفحه از یک زبان ناشناخته به <ph name="LANGUAGE_LANGUAGE"/> ترجمه شده است.</translation>
+<translation id="4923417429809017348">این صفحه از یک زبان ناشناخته به <ph name="LANGUAGE_LANGUAGE" /> ترجمه شده است.</translation>
<translation id="4926049483395192435">باید مشخص شود.</translation>
<translation id="4968547170521245791">پروکسی ممکن نیست</translation>
-<translation id="498957508165411911">از <ph name="ORIGINAL_LANGUAGE"/> به <ph name="TARGET_LANGUAGE"/> ترجمه شود؟</translation>
+<translation id="498957508165411911">از <ph name="ORIGINAL_LANGUAGE" /> به <ph name="TARGET_LANGUAGE" /> ترجمه شود؟</translation>
<translation id="5019198164206649151">پشتیبان‌گیری ذخیره در وضعیت نادرست است</translation>
<translation id="5031870354684148875">‏درباره Google Translate</translation>
+<translation id="5045550434625856497">گذرواژه نامعتبر</translation>
+<translation id="5087286274860437796">در حال حاضر گواهی سرور معتبر نیست.</translation>
<translation id="5089810972385038852">ایالت</translation>
+<translation id="5094747076828555589">‏این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیت آن مورد اعتماد Chromium نیست. علت این موضوع می‌توان پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
<translation id="5095208057601539847">استان</translation>
<translation id="5145883236150621069">کد خطا در پاسخ خط‌مشی موجود است</translation>
<translation id="5172758083709347301">دستگاه</translation>
-<translation id="5179510805599951267">به زبان <ph name="ORIGINAL_LANGUAGE"/> نیست؟ گزارش این خطا</translation>
+<translation id="5179510805599951267">به زبان <ph name="ORIGINAL_LANGUAGE" /> نیست؟ گزارش این خطا</translation>
<translation id="5190835502935405962">نوار نشانک‌ها</translation>
+<translation id="5199729219167945352">آزمایشات</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">تأیید پیمایش</translation>
<translation id="5299298092464848405">خطا در تجزیه خط‌‌مشی</translation>
+<translation id="5316812925700871227">چرخش خلاف جهت عقربه‌های ساعت</translation>
<translation id="5317780077021120954">ذخیره</translation>
<translation id="536296301121032821">تنظیمات خط‌‌مشی ذخیره نشد</translation>
-<translation id="5439770059721715174">خطای تأیید طرح در «<ph name="ERROR_PATH"/>»:‏ <ph name="ERROR"/></translation>
+<translation id="540969355065856584">این سرور نتوانست ثابت کند که <ph name="DOMAIN" /> است؛ در حال حاضر، گواهی امنیتی آن معتبر نیست. ممکن است این مشکل به دلیل پیکربندی نادرست یا قطع اتصال شما توسط حمله‌کننده ایجاد شده باشد.</translation>
+<translation id="5439770059721715174">خطای تأیید طرح در «<ph name="ERROR_PATH" />»:‏ <ph name="ERROR" /></translation>
<translation id="5455374756549232013">مهر زمان خط‌مشی نادرست است</translation>
<translation id="5470861586879999274">&amp;انجام مجدد ویرایش</translation>
<translation id="5509780412636533143">نشانک‌های مدیریت شده</translation>
<translation id="5523118979700054094">نام خط‌مشی</translation>
<translation id="552553974213252141">آیا نوشتار به درستی استخراج شده است؟</translation>
<translation id="5540224163453853">مقاله درخواستی یافت نشد.</translation>
+<translation id="5556459405103347317">تازه‌سازی</translation>
<translation id="5565735124758917034">فعال</translation>
<translation id="560412284261940334">مدیریت پشتیبانی نمی‌شود</translation>
<translation id="5629630648637658800">تنظیمات خط‌مشی بارگیری نشد</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">کاربر کنونی</translation>
<translation id="5813119285467412249">&amp;انجام مجدد افزودن</translation>
<translation id="5872918882028971132">پیشنهادات والدین</translation>
-<translation id="587701087903783706">بستن نمای مناسب دستگاه همراه</translation>
<translation id="59107663811261420">‏Google Payments این نوع کارت را برای این تاجر پشتیبانی نمی‌کند. لطفاً کارت دیگری انتخاب کنید.</translation>
+<translation id="5975083100439434680">کوچک نمایی</translation>
<translation id="5989320800837274978">‏سرور پروکسی ثابت و URL اسکریپت pac. تعیین نشده‌اند.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">بستن</translation>
+<translation id="6060685159320643512">مراقب باشید، این آزمایشات ممکن است خطرناک باشند</translation>
+<translation id="6151417162996330722">دوره اعتبار گواهینامه سرور بسیار طولانی است.</translation>
<translation id="6154808779448689242">نشانه خط‌مشی بازگشتی با نشانه فعلی تطابق ندارد</translation>
<translation id="6165508094623778733">بیشتر بدانید</translation>
<translation id="6259156558325130047">&amp;انجام مجدد ترتیب‌بندی مجدد</translation>
-<translation id="6263376278284652872">نشانک‌های <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">نشانک‌های <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">کد پستی</translation>
<translation id="6337534724793800597">فیلتر کردن خط‌مشی‌ها براساس نام</translation>
+<translation id="6387478394221739770">‏علاقه‌مند به قابلیت‌های جدید و جالب Chrome هستید؟ کانال بتای ما را در chrome.com/beta امتحان کنید.</translation>
+<translation id="6426993025560594914">تمام آزمایش‌ها در پلتفورم شما موجود است!</translation>
<translation id="6445051938772793705">کشور</translation>
<translation id="6458467102616083041">نادیده گرفته شد زیرا جستجوی پیش‌فرض توسط قانون غیرفعال شده است.</translation>
<translation id="647261751007945333">خط‌‌مشی‌های دستگاه</translation>
<translation id="6512448926095770873">ترک کردن این صفحه</translation>
<translation id="6529602333819889595">&amp;انجام مجدد حذف</translation>
<translation id="6550675742724504774">گزینه‌ها</translation>
-<translation id="6597614308054261376">می‌خواهید به <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> دسترسی پیدا کنید. این صفحه نمی‌تواند در این زمان با «صرفه‌جویی در مصرف داده» پشتیبانی شود.</translation>
-<translation id="6628463337424475685">جستجوی <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">می‌خواهید به <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> دسترسی پیدا کنید. این صفحه نمی‌تواند در این زمان با «صرفه‌جویی در مصرف داده» پشتیبانی شود.</translation>
+<translation id="6628463337424475685">جستجوی <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">این قانون قدیمی شده است.</translation>
<translation id="6646897916597483132">‏کد تأیید چهار رقمی CVC را از روی کارت‌تان وارد کنید</translation>
+<translation id="674375294223700098">خطای ناشناخته گواهی سرور.</translation>
<translation id="6753269504797312559">مقدار خط‌‌مشی</translation>
<translation id="6831043979455480757">ترجمه</translation>
<translation id="6839929833149231406">منطقه حکومتی</translation>
<translation id="6874604403660855544">&amp;انجام مجدد افزودن</translation>
<translation id="6891596781022320156">سطح خط‌مشی پشتیبانی نمی‌شود.</translation>
<translation id="6915804003454593391">کاربر:</translation>
+<translation id="6957887021205513506">به نظر می‌رسد که گواهی سرور جعلی باشد.</translation>
<translation id="6965382102122355670">تأیید</translation>
<translation id="6965978654500191972">دستگاه</translation>
<translation id="6970216967273061347">حوزه</translation>
<translation id="6973656660372572881">‏هم سرورهای پروکسی ثابت و هم آدرس اسکریپت pac. مشخص شده‌اند.</translation>
<translation id="6980028882292583085">هشدار جاوا اسکریپت</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">تلاش کردید به دامنه <ph name="DOMAIN" /> بروید اما گواهینامه‌ای که سرور ارائه کرد، دارای یک تاریخ اعتبار بسیار طولانی است و مورد اعتماد نیست.</translation>
<translation id="7087282848513945231">شهرستان</translation>
-<translation id="7108649287766967076">ترجمه به <ph name="TARGET_LANGUAGE"/> انجام نشد.</translation>
+<translation id="7108649287766967076">ترجمه به <ph name="TARGET_LANGUAGE" /> انجام نشد.</translation>
<translation id="7139724024395191329">امارت</translation>
+<translation id="7179921470347911571">اکنون راه‌اندازی مجدد شود</translation>
<translation id="7180611975245234373">بازخوانی</translation>
<translation id="7182878459783632708">هیچ خط‌مشی‌ای تنظیم نشده است</translation>
-<translation id="7186367841673660872">این صفحه از <ph name="ORIGINAL_LANGUAGE"/> به <ph name="LANGUAGE_LANGUAGE"/> ترجمه شده است</translation>
+<translation id="7186367841673660872">این صفحه از <ph name="ORIGINAL_LANGUAGE" /> به <ph name="LANGUAGE_LANGUAGE" /> ترجمه شده است</translation>
<translation id="719464814642662924">ویزا</translation>
-<translation id="7208899522964477531">جستجوی <ph name="SITE_NAME"/> برای <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">جستجوی <ph name="SITE_NAME" /> برای <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">اتصال خصوصی به <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> برقرار نمی‌شود زیرا تاریخ و زمان رایانه شما (<ph name="DATE_AND_TIME" />) نادرست است.</translation>
<translation id="7275334191706090484">نشانک‌های مدیریت شده</translation>
<translation id="7298195798382681320">توصیه می‌شود</translation>
<translation id="7334320624316649418">&amp;انجام مجدد ترتیب‌بندی مجدد</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">جاوا اسکریپت</translation>
<translation id="7537536606612762813">اجباری</translation>
<translation id="7542995811387359312">تکمیل خودکار کارت اعتباری غیر فعال است زیرا این فرم از یک اتصال امن استفاده نمی‌کند.</translation>
-<translation id="7568593326407688803">این صفحه به <ph name="ORIGINAL_LANGUAGE"/> است، آیا مایلید ترجمه شود؟</translation>
+<translation id="7567204685887185387">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ ممکن است گواهی امنیتی آن به صورت تقلبی صادر شده باشد. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
+<translation id="7568593326407688803">این صفحه به <ph name="ORIGINAL_LANGUAGE" /> است، آیا مایلید ترجمه شود؟</translation>
<translation id="7569952961197462199">‏کارت اعتباری از Chrome پاک شود؟</translation>
-<translation id="7600965453749440009">هرگز <ph name="LANGUAGE"/> ترجمه نشود</translation>
-<translation id="7610193165460212391">مقدار خارج از محدوده <ph name="VALUE"/> است.</translation>
+<translation id="7592362899630581445">گواهی سرور محدودیت‌های نام را نقض می‌کند.</translation>
+<translation id="7600965453749440009">هرگز <ph name="LANGUAGE" /> ترجمه نشود</translation>
+<translation id="7610193165460212391">مقدار خارج از محدوده <ph name="VALUE" /> است.</translation>
+<translation id="7674629440242451245">‏علاقه‌مند به قابلیت‌های جدید و جالب Chrome هستید؟ کانال برنامه‌نویسان ما را در chrome.com/dev امتحان کنید.</translation>
<translation id="7752995774971033316">مدیریت نشده</translation>
+<translation id="7761701407923456692">‏گواهی سرور با URL مطابقت ندارد.</translation>
<translation id="777702478322588152">حوزه اداری</translation>
<translation id="7791543448312431591">افزودن</translation>
<translation id="7805768142964895445">وضعیت</translation>
<translation id="7813600968533626083">‏پیشنهاد فرم از Chrome پاک شود؟</translation>
<translation id="7887683347370398519">‏CVC را بررسی کرده و دوباره امتحان کنید</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">گواهی سرور هنوز معتبر نیست.</translation>
<translation id="7956713633345437162">نشانک‌های تلفن‌ همراه</translation>
<translation id="7961015016161918242">هرگز</translation>
<translation id="7977590112176369853">&lt;واردکردن پرسش&gt;</translation>
-<translation id="7983301409776629893">همیشه <ph name="ORIGINAL_LANGUAGE"/> به <ph name="TARGET_LANGUAGE"/> ترجمه شود</translation>
+<translation id="7983301409776629893">همیشه <ph name="ORIGINAL_LANGUAGE" /> به <ph name="TARGET_LANGUAGE" /> ترجمه شود</translation>
<translation id="7988324688042446538">نشانک‌های دسک‌تاپ</translation>
<translation id="7995512525968007366">تعیین نشده</translation>
-<translation id="8034522405403831421">این صفحه به زبان <ph name="SOURCE_LANGUAGE"/> است. مایلید آن را به <ph name="TARGET_LANGUAGE"/> ترجمه کنید؟</translation>
+<translation id="8003882219468422867">لغو شرکتی</translation>
+<translation id="8034522405403831421">این صفحه به زبان <ph name="SOURCE_LANGUAGE" /> است. مایلید آن را به <ph name="TARGET_LANGUAGE" /> ترجمه کنید؟</translation>
<translation id="8088680233425245692">مشاهده مقاله ناموفق بود.</translation>
<translation id="8091372947890762290">فعال‌سازی در سرور در حالت تعلیق است</translation>
<translation id="8194797478851900357">&amp;واگرد انتقال</translation>
-<translation id="8201077131113104583">نشانی اینترنتی به‌روزرسانی نامعتبر برای برنامه افزودنی با شناسه «<ph name="EXTENSION_ID"/>».</translation>
+<translation id="8201077131113104583">نشانی وب به‌روزرسانی نامعتبر برای برنامه افزودنی با شناسه «<ph name="EXTENSION_ID" />».</translation>
<translation id="8208216423136871611">ذخیره نشود</translation>
<translation id="8218327578424803826">مکان اختصاص یافته:</translation>
<translation id="8249320324621329438">آخرین واکشی شده:</translation>
+<translation id="8294431847097064396">منبع</translation>
<translation id="8308427013383895095">ترجمه انجام نشد چون مشکلی در اتصال به شبکه رخ داد.</translation>
<translation id="8311778656528046050">آیا مطمئن هستید که می‌خواهید این صفحه را تازه‌سازی کنید؟</translation>
<translation id="8349305172487531364">نوار نشانک‌ها</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">اعمال برای</translation>
<translation id="8530504477309582336">‏Google Payments این نوع کارت را پشتیبانی نمی‌کند. لطفاً کارت دیگری انتخاب کنید.</translation>
<translation id="8553075262323480129">ترجمه انجام نشد زیرا زبان صفحه تعیین نشد.</translation>
-<translation id="8571890674111243710">ترجمه صفحه به <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">اتصال خصوصی به <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> انجام نمی‌شود، زیرا تاریخ و زمان دستگاه شما (<ph name="DATE_AND_TIME" />) نادرست است.</translation>
+<translation id="8571890674111243710">ترجمه صفحه به <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">بازنشانی همه به موارد پیش‌فرض</translation>
<translation id="8713130696108419660">امضای اولیه خراب</translation>
<translation id="8725066075913043281">سعی مجدد</translation>
+<translation id="8738058698779197622">‏به منظور برقراری یک اتصال امن، لازم است که ساعت شما به درستی تنظیم شود. زیرا گواهینامه‌هایی که وب‌سایت‌ها برای شناسایی خودشان استفاده می‌کنند تنها برای دوره‌های زمانی خاصی معتبر هستند. از آنجایی که ساعت دستگاه نادرست است، Chromium نمی‌تواند این گواهینامه‌ها را تأیید کند.</translation>
<translation id="8790007591277257123">&amp;انجام مجدد حذف</translation>
<translation id="8804164990146287819">خط‌مشی رازداری</translation>
+<translation id="8820817407110198400">نشانک‌ها</translation>
<translation id="8824019021993735287">‏Chrome در حال حاضر نمی‌تواند کارت‌تان را تأیید کند. لطفاً بعداً دوباره امتحان کنید.</translation>
<translation id="8834246243508017242">فعال‌سازی تکمیل خودکار با استفاده از مخاطبین…</translation>
<translation id="883848425547221593">نشانک‌های دیگر</translation>
+<translation id="884923133447025588">هیچ مکانیزم ابطالی یافت نشد.</translation>
<translation id="8866481888320382733">خطا در تجزیه تنظیمات خط‌مشی</translation>
<translation id="8876793034577346603">پیکربندی شبکه نتوانست تجزیه شود.</translation>
<translation id="8891727572606052622">حالت پروکسی نامعتبر است.</translation>
-<translation id="8940229512486821554">اجرای فرمان <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">متأسفیم، این آزمایش بر روی دستگاه شما قابل انجام نیست.</translation>
+<translation id="8903921497873541725">بزرگ‌نمایی</translation>
+<translation id="8932102934695377596">ساعت شما عقب است</translation>
+<translation id="8940229512486821554">اجرای فرمان <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">گواهی سرور منقضی شده است.</translation>
<translation id="8988760548304185580">‏تاریخ انقضا و کد تأیید سه رقمی CVC را از پشت کارت‌تان وارد کنید</translation>
-<translation id="9020542370529661692">این صفحه به <ph name="TARGET_LANGUAGE"/> ترجمه شده است</translation>
+<translation id="901974403500617787">پرچم‌هایی که در تمام سیستم اعمال می‌شوند فقط توسط مالک قابل تنظیم هستند: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">این صفحه به <ph name="TARGET_LANGUAGE" /> ترجمه شده است</translation>
+<translation id="9049981332609050619">شما سعی کردید به <ph name="DOMAIN" /> دسترسی داشته باشید، اما سرور یک گواهی نامعتبر را نشان داد.</translation>
<translation id="9125941078353557812">‏کد تأیید سه رقمی CVC را از پشت کارت‌تان وارد کنید</translation>
<translation id="9137013805542155359">نمایش مورد اصلی</translation>
<translation id="9148507642005240123">&amp;واگرد ویرایش</translation>
<translation id="9154176715500758432">ماندن در این صفحه</translation>
<translation id="9170848237812810038">&amp;واگرد</translation>
+<translation id="917450738466192189">گواهی سرور نامعتبر است.</translation>
+<translation id="9187827965378254003">وای، به نظر می‌رسد در حال حاضر هیچ آزمایشی موجود نیست.</translation>
<translation id="9207861905230894330">افزودن مقاله ناموفق بود.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">پاک کردن فرم</translation>
+<translation id="988159990683914416">ساخت برنامه‌نویس</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_fi.xtb b/chromium/components/strings/components_strings_fi.xtb
index 24c0f51ff15..d1ac05d8a25 100644
--- a/chromium/components/strings/components_strings_fi.xtb
+++ b/chromium/components/strings/components_strings_fi.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="fi">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fi">
+<translation id="1032854598605920125">Käännä myötäpäivään</translation>
<translation id="1055184225775184556">K&amp;umoa lisäys</translation>
<translation id="106701514854093668">Työpöytäkirjanmerkit</translation>
-<translation id="1103523840287552314">Käännä <ph name="LANGUAGE"/> aina</translation>
+<translation id="1080116354587839789">Sovita leveyteen</translation>
+<translation id="1103523840287552314">Käännä <ph name="LANGUAGE" /> aina</translation>
<translation id="1113869188872983271">K&amp;umoa uudelleenjärjestely</translation>
<translation id="111844081046043029">Haluatko varmasti poistua tältä sivulta?</translation>
<translation id="112840717907525620">Käytännön välimuisti on OK</translation>
<translation id="1132774398110320017">Chromen automaattisen täytön asetukset…</translation>
-<translation id="1152921474424827756">Käytä osoitteen <ph name="URL"/> <ph name="BEGIN_LINK"/>välimuistiversiota<ph name="END_LINK"/></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="1152921474424827756">Käytä osoitteen <ph name="URL" /> <ph name="BEGIN_LINK" />välimuistiversiota<ph name="END_LINK" /></translation>
+<translation id="121201262018556460">Yritit yhdistää verkkotunnukseen <ph name="DOMAIN" />, mutta palvelin esitti varmenteen, joka käyttää heikkoa avainta. Hakkeri on saattanut murtaa avaimen. Palvelin ei siis välttämättä ole tavoittelemasi palvelin, vaan saatat viestiä hakkerin kanssa.</translation>
<translation id="1227224963052638717">Tuntematon käytäntö.</translation>
<translation id="1227633850867390598">Piilota arvo</translation>
<translation id="1228893227497259893">Väärä entiteettitunnus</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Käyttöönoton verkkotunnus:</translation>
<translation id="1344588688991793829">Chromiumin automaattisen täytön asetukset…</translation>
<translation id="1426410128494586442">Kyllä</translation>
+<translation id="1430915738399379752">Tulosta</translation>
<translation id="1455235771979731432">Korttia todennettaessa tapahtui virhe. Tarkista internetyhteys ja yritä uudelleen.</translation>
<translation id="1491151370853475546">Päivitä tämä sivu</translation>
<translation id="1549470594296187301">Tämän ominaisuuden käyttö edellyttää JavaScriptiä.</translation>
-<translation id="1639239467298939599">Ladataan</translation>
<translation id="1640180200866533862">Käyttäjäkäytännöt</translation>
<translation id="1644184664548287040">Verkkoasetukset ovat virheelliset eikä niitä voi tuoda.</translation>
-<translation id="1693754753824026215">Sivu osoitteessa <ph name="SITE"/> ilmoittaa:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne vanhentui eilen. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä. Tietokoneesi kellonaika on tällä hetkellä <ph name="CURRENT_DATE" />. Onko se oikein? Jos ei, korjaa järjestelmän kellonaika ja päivitä sivu.}other{Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne vanhentui # päivää sitten. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä. Tietokoneesi kellonaika on tällä hetkellä <ph name="CURRENT_DATE" />. Onko se oikein? Jos ei, korjaa järjestelmän kellonaika ja päivitä sivu.}}</translation>
+<translation id="168841957122794586">Palvelinvarmenne sisältää heikon salausavaimen.</translation>
+<translation id="1693754753824026215">Sivu osoitteessa <ph name="SITE" /> ilmoittaa:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; laitteesi käyttöjärjestelmä ei luota sen suojausvarmenteeseen. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
<translation id="1821930232296380041">Pyyntö on virheellinen tai pyynnön parametrit ovat virheelliset</translation>
-<translation id="1853748787962613237">Artikkelin näyttäminen epäonnistui.</translation>
<translation id="1871208020102129563">Välityspalvelin on asetettu käyttämään kiinteitä välityspalvelimia, ei .pac-URL-osoitetta.</translation>
-<translation id="1875753206475436906">heuristinen tyyppi: <ph name="HEURISTIC_TYPE"/>
- palvelimen tyyppi: <ph name="SERVER_TYPE"/>
- kentän allekirjoitus: <ph name="FIELD_SIGNATURE"/>
- lomakkeen allekirjoitus: <ph name="FORM_SIGNATURE"/>
- kokeilutunnus: <ph name="EXPERIMENT_ID"/></translation>
-<translation id="194030505837763158">Siirry osoitteeseen <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Verkkotunnuksen <ph name="DOMAIN"/> kirjanmerkit</translation>
+<translation id="194030505837763158">Siirry osoitteeseen <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Verkkotunnuksen <ph name="DOMAIN" /> kirjanmerkit</translation>
<translation id="1973335181906896915">Sarjaesittämisen virhe</translation>
+<translation id="1974060860693918893">Lisäasetukset</translation>
<translation id="2025186561304664664">Välityspalvelimen asetus: automaattisesti määritetty.</translation>
<translation id="2025623846716345241">Vahvista päivitys</translation>
-<translation id="2030481566774242610">Tarkoititko: <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Tarkoititko: <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Postinumero</translation>
<translation id="20817612488360358">Järjestelmän välityspalvelinasetukset on määritetty käytettäviksi, mutta erilliset välityspalvelimen asetukset on myös määritetty.</translation>
<translation id="2094505752054353250">Verkkotunnukset eivät ole yhteensopivat</translation>
<translation id="2096368010154057602">Osasto</translation>
<translation id="2113977810652731515">Kortti</translation>
-<translation id="2114841414352855701">Ei käytetä – käytännön <ph name="POLICY_NAME"/> ohittama.</translation>
+<translation id="2114841414352855701">Ei käytetä – käytännön <ph name="POLICY_NAME" /> ohittama.</translation>
+<translation id="2128531968068887769">Asiakassovellus</translation>
<translation id="213826338245044447">Mobiilikirjanmerkit</translation>
+<translation id="2171101176734966184">Yritit yhdistää verkkotunnukseen <ph name="DOMAIN" />, mutta palvelin esitti varmenteen, joka käyttää heikkoa allekirjoitusalgoritmia. Tämä tarkoittaa sitä, että palvelimen esittämät tunnistetiedot saattavat olla väärennettyjä. Palvelin ei siis välttämättä ole tavoittelemasi palvelin, vaan saatat viestiä hakkerin kanssa.</translation>
<translation id="2181821976797666341">Käytännöt</translation>
<translation id="2212735316055980242">Käytäntöä ei löydy</translation>
<translation id="2213606439339815911">Noudetaan merkintöjä…</translation>
<translation id="225207911366869382">Tämän käytännön arvo on vanhentunut.</translation>
<translation id="2262243747453050782">HTTP-virhe</translation>
-<translation id="2270192940992995399">Artikkelia ei löydy.</translation>
-<translation id="2328300916057834155">Ohitettiin virheellinen kirjanmerkki kohdassa <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Ei käytettävissä olevat kokeilut</translation>
+<translation id="229702904922032456">Pää- tai keskitason varmenne on vanhentunut.</translation>
+<translation id="2328300916057834155">Ohitettiin virheellinen kirjanmerkki kohdassa <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Muut kirjanmerkit</translation>
<translation id="2359808026110333948">Jatka</translation>
<translation id="2367567093518048410">Taso</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="2396249848217231973">K&amp;umoa poisto</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="2455981314101692989">Tämä verkkosivu on poistanut tämän lomakkeen automaattisen täytön käytöstä.</translation>
<translation id="2479410451996844060">Virheellinen hakukoneen URL-osoite.</translation>
+<translation id="2491120439723279231">Palvelimen varmenteessa on virheitä.</translation>
<translation id="2495083838625180221">JSON-jäsentäjä</translation>
<translation id="2498091847651709837">Skannaa uusi kortti</translation>
<translation id="2556876185419854533">K&amp;umoa muokkaus</translation>
-<translation id="2581221116934462656">Haluatko, että <ph name="PRODUCT_NAME"/> ehdottaa sivuston kielellä <ph name="LANGUAGE_NAME"/> kirjoitettujen sivujen kääntämistä seuraavalla kerralla?</translation>
+<translation id="2581221116934462656">Haluatko, että <ph name="PRODUCT_NAME" /> ehdottaa sivuston kielellä <ph name="LANGUAGE_NAME" /> kirjoitettujen sivujen kääntämistä seuraavalla kerralla?</translation>
<translation id="2587841377698384444">Hakemistosovellusliittymän tunnus:</translation>
<translation id="2597378329261239068">Tämä asiakirja on suojattu salasanalla. Anna salasana.</translation>
+<translation id="2625385379895617796">Kellosi edistää</translation>
<translation id="2639739919103226564">Tila:</translation>
+<translation id="2653659639078652383">Lähetä</translation>
<translation id="2704283930420550640">Arvo ei vastaa muotoa.</translation>
<translation id="2721148159707890343">Pyyntö onnistui</translation>
+<translation id="2728127805433021124">Palvelimen varmenne on allekirjoitettu heikolla allekirjoitusalgoritmilla.</translation>
<translation id="2774256287122201187">Voit jatkaa. Jos jatkat sivulle, tätä varoitusta ei näytetä uudelleen viiteen minuuttiin.</translation>
<translation id="277499241957683684">Laitetallenne puuttuu</translation>
<translation id="2835170189407361413">Tyhjennä lomake</translation>
-<translation id="2855922900409897335">Vahvista <ph name="CREDIT_CARD"/>.</translation>
+<translation id="2855922900409897335">Vahvista <ph name="CREDIT_CARD" />.</translation>
+<translation id="2915500479781995473">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne on vanhentunut. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä. Tietokoneesi kellon aika on tällä hetkellä <ph name="CURRENT_TIME" />. Onko se oikeassa? Jos ei, siirrä kello oikeaan aikaan ja päivitä sivu.</translation>
+<translation id="2922350208395188000">Palvelimen varmennetta ei voi tarkistaa.</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="2958431318199492670">Verkkoasetukset eivät noudata ONC-standardia. Kaikkia asetuksia ei välttämättä tuoda.</translation>
<translation id="2972581237482394796">&amp;Tee uudelleen</translation>
-<translation id="3010559122411665027">Luettelokohde &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Luettelokohde "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Väärä käytäntötyyppi</translation>
<translation id="3105172416063519923">Laitteen tunnus:</translation>
<translation id="3145945101586104090">Vastauksen purkaminen epäonnistui</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Saari</translation>
<translation id="3219579145727097045">Anna vanhenemispäivä ja nelinumeroinen CVC luottokortin etupuolelta.</translation>
-<translation id="3228969707346345236">Käännös epäonnistui, koska sivun kieli on jo <ph name="LANGUAGE"/>.</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="3228969707346345236">Käännös epäonnistui, koska sivun kieli on jo <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">K&amp;umoa uudelleenjärjestely</translation>
+<translation id="3286538390144397061">Käynnistä uudelleen</translation>
<translation id="333371639341676808">Estä tätä sivua luomasta muita viestejä.</translation>
-<translation id="3369366829301677151">Päivitä ja vahvista <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">asetuksissa</translation>
+<translation id="3369192424181595722">Väärä kellonaika</translation>
+<translation id="3369366829301677151">Päivitä ja vahvista <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Poistettu käytöstä</translation>
<translation id="3377188786107721145">Virhe jäsennettäessä käytäntöä</translation>
<translation id="3380365263193509176">Tuntematon virhe</translation>
<translation id="3380864720620200369">Asiakastunnus:</translation>
<translation id="3427342743765426898">&amp;Toista muokkaus</translation>
+<translation id="3435896845095436175">Ota käyttöön</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Hakuväli:</translation>
+<translation id="3462200631372590220">Piilota lisäasetukset</translation>
+<translation id="3528171143076753409">Palvelimen varmenne ei ole luotettava.</translation>
<translation id="3542684924769048008">Käytä salasanaa kohteeseen:</translation>
<translation id="3583757800736429874">&amp;Toista siirto</translation>
<translation id="3623476034248543066">Näytä arvo</translation>
+<translation id="3648607100222897006">Nämä kokeelliset ominaisuudet voivat muuttua, rikkoutua tai kadota milloin tahansa. Emme takaa mitä tapahtuu, jos otat kokeiluja käyttöön – selaimesi saattaa jopa syttyä palamaan. Vitsit sikseen: selaimesi voi oikeasti poistaa kaikki tietosi, tai tietosuojasi voi vaarantua arvaamattomilla tavoilla. Kaikki tämän selaimen käyttäjät voivat käyttää käyttöön ottamiasi kokeiluita. Jatka omalla vastuullasi.</translation>
<translation id="3650584904733503804">Todennus onnistui</translation>
<translation id="370665806235115550">Ladataan...</translation>
<translation id="3712624925041724820">Käyttöluvat ovat lopussa</translation>
<translation id="3739623965217189342">Kopioimasi linkki</translation>
<translation id="375403751935624634">Käännös epäonnistui palvelinvirheen vuoksi.</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>
<translation id="3885155851504623709">Kunta</translation>
<translation id="3934680773876859118">PDF-asiakirjan lataaminen epäonnistui</translation>
<translation id="3963721102035795474">Lukijatila</translation>
<translation id="4030383055268325496">K&amp;umoa lisäys</translation>
-<translation id="4058922952496707368">Avain <ph name="SUBKEY"/>: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">Varoitus</translation>
+<translation id="4058922952496707368">Avain <ph name="SUBKEY" />: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Välityspalvelinmääritykset on asetettu käyttämään .pac-URL-osoitteita, ei kiinteitä välityspalvelimia.</translation>
<translation id="409504436206021213">Älä päivitä</translation>
<translation id="4103249731201008433">Laitteen sarjanumero on virheellinen</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Virheellinen allekirjoitus</translation>
<translation id="4269787794583293679">(Ei käyttäjänimeä)</translation>
<translation id="4300246636397505754">Ylätason ehdotukset</translation>
-<translation id="4372948949327679948">Odotettu <ph name="VALUE_TYPE"/>-arvo.</translation>
+<translation id="4325863107915753736">Artikkelia ei löydy</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="4394049700291259645">Poista käytöstä</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="443673843213245140">Välityspalvelinta ei saa käyttää, mutta erilliset välityspalvelimen asetukset on määritetty.</translation>
-<translation id="4506176782989081258">Todennusvirhe: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Todennusvirhe: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Poistetaanko osoite Chromen tiedoista?</translation>
<translation id="4594403342090139922">K&amp;umoa poisto</translation>
<translation id="4607653538520819196">Data Saver ei voi lähettää tätä sivua välityspalvelimelle.</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="4726672564094551039">Päivitä käytännöt</translation>
+<translation id="4728558894243024398">Käyttöympäristö</translation>
+<translation id="4771973620359291008">Tapahtui tuntematon virhe.</translation>
<translation id="4800132727771399293">Tarkista vanhenemispäivä ja CVC ja yritä uudelleen.</translation>
<translation id="4813512666221746211">Verkkovirhe</translation>
+<translation id="4816492930507672669">Sovita sivulle</translation>
<translation id="4850886885716139402">Näytä</translation>
-<translation id="4923417429809017348">Tämä sivu on käännetty tuntemattomasta kielestä kielelle <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Tämä sivu on käännetty tuntemattomasta kielestä kielelle <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">On määritettävä.</translation>
<translation id="4968547170521245791">Ei voi lähettää välityspalvelimelle</translation>
-<translation id="498957508165411911">Käännetäänkö kielestä <ph name="ORIGINAL_LANGUAGE"/> kielelle <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Käännetäänkö kielestä <ph name="ORIGINAL_LANGUAGE" /> kielelle <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Tallennustila on virheellisessä tilassa</translation>
<translation id="5031870354684148875">Tietoja Google-kääntäjästä</translation>
+<translation id="5045550434625856497">Väärä salasana</translation>
+<translation id="5087286274860437796">Palvelimen varmenne ei ole tällä hetkellä kelvollinen.</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="5145883236150621069">Käytäntövastaus sisältää virhekoodin</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="5179510805599951267">Eikö kieli ole <ph name="ORIGINAL_LANGUAGE" />? Ilmoita virheestä</translation>
<translation id="5190835502935405962">Kirjanmerkkipalkki</translation>
+<translation id="5199729219167945352">Kokeilut</translation>
+<translation id="5251803541071282808">Pilvi</translation>
<translation id="5295309862264981122">Vahvista liikkuminen</translation>
<translation id="5299298092464848405">Virhe jäsennettäessä käytäntöä</translation>
+<translation id="5316812925700871227">Käännä vastapäivään</translation>
<translation id="5317780077021120954">Tallenna</translation>
<translation id="536296301121032821">Käytännön asetuksien tallentaminen epäonnistui</translation>
-<translation id="5439770059721715174">Mallin todennusvirhe kohdassa <ph name="ERROR_PATH"/>: <ph name="ERROR"/></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="5439770059721715174">Mallin todennusvirhe kohdassa <ph name="ERROR_PATH" />: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Virheellinen käytännön aikaleima</translation>
<translation id="5470861586879999274">&amp;Toista muokkaus</translation>
<translation id="5509780412636533143">Hallinnoidut kirjanmerkit</translation>
<translation id="5523118979700054094">Käytännön nimi</translation>
<translation id="552553974213252141">Noudettiinko teksti oikein?</translation>
<translation id="5540224163453853">Pyydettyä artikkelia ei löydy.</translation>
+<translation id="5556459405103347317">Lataa uudelleen</translation>
<translation id="5565735124758917034">Aktiivinen</translation>
<translation id="560412284261940334">Hallintaa ei tueta</translation>
<translation id="5629630648637658800">Käytännön asetuksien lataaminen epäonnistui</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Nykyinen käyttäjä</translation>
<translation id="5813119285467412249">&amp;Toista lisäys</translation>
<translation id="5872918882028971132">Ylätason ehdotukset</translation>
-<translation id="587701087903783706">Sulje mobiililaitteisiin sopiva näkymä</translation>
<translation id="59107663811261420">Google Payments ei tue tämän tyyppisen kortin käyttämistä ostoksien tekemiseen tältä myyjältä. Valitse eri kortti.</translation>
+<translation id="5975083100439434680">Loitonna</translation>
<translation id="5989320800837274978">Kiinteitä välityspalvelimia tai .pac-URL-osoitetta ei ole määritetty.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Sulje</translation>
+<translation id="6060685159320643512">Varoitus, nämä kokeilut saattavat puraista</translation>
+<translation id="6151417162996330722">Palvelimen varmenteen voimassaoloaika on liian pitkä.</translation>
<translation id="6154808779448689242">Palautettu käytännön tunnus ei vastaa nykyistä tunnusta</translation>
<translation id="6165508094623778733">Lisätietoja</translation>
<translation id="6259156558325130047">&amp;Toista uudelleenjärjestely</translation>
-<translation id="6263376278284652872">Verkkotunnuksen <ph name="DOMAIN"/> kirjanmerkit</translation>
+<translation id="6263376278284652872">Verkkotunnuksen <ph name="DOMAIN" /> kirjanmerkit</translation>
<translation id="6282194474023008486">Postinumero</translation>
<translation id="6337534724793800597">Suodata käytäntöjä nimen mukaan</translation>
+<translation id="6387478394221739770">Oletko kiinnostunut Chromen uusista jännittävistä ominaisuuksista? Kokeile beta-kanavaa osoitteessa chrome.com/beta.</translation>
+<translation id="6426993025560594914">Kaikki kokeilut ovat käytettävissä käyttöympäristössäsi!</translation>
<translation id="6445051938772793705">Maa</translation>
<translation id="6458467102616083041">Ohitettu, koska oletushaku on poistettu käytöstä käytännön mukaan.</translation>
<translation id="647261751007945333">Laitekäytännöt</translation>
<translation id="6512448926095770873">Poistu tältä sivulta</translation>
<translation id="6529602333819889595">&amp;Toista poisto</translation>
<translation id="6550675742724504774">Asetukset</translation>
-<translation id="6597614308054261376">Yrität avata sivuston <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Data Saver ei voi lähettää tätä sivua välityspalvelimelle tällä hetkellä.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/>-haku</translation>
+<translation id="6597614308054261376">Yrität avata sivuston <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Data Saver ei voi lähettää tätä sivua välityspalvelimelle tällä hetkellä.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" />-haku</translation>
<translation id="6644283850729428850">Tämä käytäntö on vanhentunut.</translation>
<translation id="6646897916597483132">Anna nelinumeroinen CVC luottokortin etupuolelta.</translation>
+<translation id="674375294223700098">Tuntematon palvelimen varmennevirhe.</translation>
<translation id="6753269504797312559">Käytännön arvo</translation>
<translation id="6831043979455480757">Käännä</translation>
<translation id="6839929833149231406">Alue</translation>
<translation id="6874604403660855544">&amp;Toista lisäys</translation>
<translation id="6891596781022320156">Käytännön tasoa ei tueta.</translation>
<translation id="6915804003454593391">Käyttäjä:</translation>
+<translation id="6957887021205513506">Palvelimen varmenne näyttää olevan väärennös.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">JavaScript-ilmoitus</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Yritit muodostaa yhteyden verkkotunnukseen <ph name="DOMAIN" />, mutta palvelin esitti varmenteen, joka on voimassa liian kauan ollakseen luotettava.</translation>
<translation id="7087282848513945231">Kunta</translation>
-<translation id="7108649287766967076">Käännös kielelle <ph name="TARGET_LANGUAGE"/> epäonnistui.</translation>
+<translation id="7108649287766967076">Käännös kielelle <ph name="TARGET_LANGUAGE" /> epäonnistui.</translation>
<translation id="7139724024395191329">Emiirikunta</translation>
+<translation id="7179921470347911571">Käynnistä uudelleen</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="7186367841673660872">Tämä sivu on käännetty kielestä<ph name="ORIGINAL_LANGUAGE" />kielelle<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Haku sivustosta: <ph name="SITE_NAME"/> termillä: <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Haku sivustosta: <ph name="SITE_NAME" /> termillä: <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Verkkotunnukseen <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei voi muodostaa salattua yhteyttä, koska tietokoneesi aika ja päivämäärä (<ph name="DATE_AND_TIME" />) ovat virheelliset.</translation>
<translation id="7275334191706090484">Hallinnoidut kirjanmerkit</translation>
<translation id="7298195798382681320">Suositus</translation>
<translation id="7334320624316649418">&amp;Toista uudelleenjärjestely</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Pakollinen</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="7568593326407688803">Tämä sivu on kirjoitettu kielellä<ph name="ORIGINAL_LANGUAGE"/>Haluatko kääntää sen?</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="7568593326407688803">Tämä sivu on kirjoitettu kielellä<ph name="ORIGINAL_LANGUAGE" />Haluatko kääntää sen?</translation>
<translation id="7569952961197462199">Poistetaanko luottokortti Chromen tiedoista?</translation>
-<translation id="7600965453749440009">Älä koskaan käännä kieltä <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Arvo on alueen ulkopuolella (<ph name="VALUE"/>).</translation>
+<translation id="7592362899630581445">Palvelimen varmenne rikkoo nimirajoituksia.</translation>
+<translation id="7600965453749440009">Älä koskaan käännä kieltä <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Arvo on alueen ulkopuolella (<ph name="VALUE" />).</translation>
+<translation id="7674629440242451245">Oletko kiinnostunut Chromen uusista jännittävistä ominaisuuksista? Kokeile kehittäjäkanavaa osoitteessa chrome.com/dev.</translation>
<translation id="7752995774971033316">Ei hallinnoida</translation>
+<translation id="7761701407923456692">Palvelimen varmenne ei vastaa URL-osoitetta.</translation>
<translation id="777702478322588152">Prefektuuri</translation>
<translation id="7791543448312431591">Lisää</translation>
<translation id="7805768142964895445">Tila</translation>
<translation id="7813600968533626083">Poistetaanko lomake-ehdotus Chromen tiedoista?</translation>
<translation id="7887683347370398519">Tarkista CVC ja yritä uudelleen.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Palvelimen varmenne ei ole vielä voimassa.</translation>
<translation id="7956713633345437162">Mobiilikirjanmerkit</translation>
<translation id="7961015016161918242">Ei koskaan</translation>
<translation id="7977590112176369853">&lt;anna hakulauseke&gt;</translation>
-<translation id="7983301409776629893">Käännä aina kielestä <ph name="ORIGINAL_LANGUAGE"/> kielelle <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Käännä aina kielestä <ph name="ORIGINAL_LANGUAGE" /> kielelle <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Työpöytäkirjanmerkit</translation>
<translation id="7995512525968007366">Ei määritetty</translation>
-<translation id="8034522405403831421">Sivu on kirjoitettu kielellä <ph name="SOURCE_LANGUAGE"/>. Haluatko kääntää sen kielelle <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Yrityksen ohitus</translation>
+<translation id="8034522405403831421">Sivu on kirjoitettu kielellä <ph name="SOURCE_LANGUAGE" />. Haluatko kääntää sen kielelle <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Artikkelin näyttäminen epäonnistui.</translation>
<translation id="8091372947890762290">Aktivointi odottaa palvelimella</translation>
<translation id="8194797478851900357">K&amp;umoa siirto</translation>
-<translation id="8201077131113104583">Laajennuksella, jonka tunnus on <ph name="EXTENSION_ID"/>, on virheellinen päivitys-URL-osoite.</translation>
+<translation id="8201077131113104583">Laajennuksella, jonka tunnus on <ph name="EXTENSION_ID" />, on virheellinen päivitys-URL-osoite.</translation>
<translation id="8208216423136871611">Älä tallenna</translation>
<translation id="8218327578424803826">Määrätty sijainti:</translation>
<translation id="8249320324621329438">Viimeksi haettu:</translation>
+<translation id="8294431847097064396">Lähde</translation>
<translation id="8308427013383895095">Käännös epäonnistui, koska verkkoyhteydessä esiintyi ongelmia.</translation>
<translation id="8311778656528046050">Haluatko varmasti päivittää tämän sivun?</translation>
<translation id="8349305172487531364">Kirjanmerkkipalkki</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Käyttöalue</translation>
<translation id="8530504477309582336">Google Payments ei tue tämän tyyppistä korttia. Valitse eri kortti.</translation>
<translation id="8553075262323480129">Käännös epäonnistui, sillä sivun kieltä ei voitu määrittää.</translation>
-<translation id="8571890674111243710">Käännetään sivua kielelle <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Verkkotunnukseen <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei voi muodostaa salattua yhteyttä, koska laitteesi aika ja päivämäärä (<ph name="DATE_AND_TIME" />) ovat virheelliset.</translation>
+<translation id="8571890674111243710">Käännetään sivua kielelle <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Palauta kaikki oletusarvoon</translation>
<translation id="8713130696108419660">Virheelliset nimikirjaimet</translation>
<translation id="8725066075913043281">Yritä uudelleen</translation>
+<translation id="8738058698779197622">Kellosi täytyy asettaa oikeaan aikaan, jotta salattu yhteys voidaan muodostaa. Tämä johtuu siitä, että verkkosivustojen tunnistamisessa käytettävät varmenteet ovat voimassa vain tiettyinä ajanjaksoina. Chromium ei voi vahvistaa varmenteita, koska laitteesi kello on väärässä ajassa.</translation>
<translation id="8790007591277257123">&amp;Toista poisto</translation>
<translation id="8804164990146287819">Tietosuojakäytäntö</translation>
+<translation id="8820817407110198400">Kirjanmerkit</translation>
<translation id="8824019021993735287">Chrome ei voinut vahvistaa korttiasi. Yritä myöhemmin uudelleen.</translation>
<translation id="8834246243508017242">Ota käyttöön automaattinen täyttö kontaktien avulla…</translation>
<translation id="883848425547221593">Muut kirjanmerkit</translation>
+<translation id="884923133447025588">Kumoamisjärjestelmää ei löytynyt.</translation>
<translation id="8866481888320382733">Virhe jäsennettäessä käytännön asetuksia</translation>
<translation id="8876793034577346603">Verkkoasetuksia ei voitu jäsentää.</translation>
<translation id="8891727572606052622">Virheellinen välityspalvelimen tila.</translation>
-<translation id="8940229512486821554">Suorita laajennuksessa <ph name="EXTENSION_NAME"/> komento: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Tämä kokeilu ei ole käytettävissä käyttöympäristössäsi.</translation>
+<translation id="8903921497873541725">Lähennä</translation>
+<translation id="8932102934695377596">Kellosi jätättää</translation>
+<translation id="8940229512486821554">Suorita laajennuksessa <ph name="EXTENSION_NAME" /> komento: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Palvelimen varmenne on vanhentunut.</translation>
<translation id="8988760548304185580">Anna vanhenemispäivä ja kolminumeroinen CVC luottokortin takapuolelta.</translation>
-<translation id="9020542370529661692">Sivu on käännetty kielelle <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Koko järjestelmään vaikuttavat merkinnät voi tehdä vain omistaja: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Sivu on käännetty kielelle <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Yritit muodostaa yhteyden verkkotunnukseen <ph name="DOMAIN" />, mutta palvelin esitti virheellisen varmenteen.</translation>
<translation id="9125941078353557812">Anna kolminumeroinen CVC luottokortin takapuolelta.</translation>
<translation id="9137013805542155359">Näytä alkuperäinen</translation>
<translation id="9148507642005240123">K&amp;umoa muokkaus</translation>
<translation id="9154176715500758432">Pysy tällä sivulla</translation>
<translation id="9170848237812810038">K&amp;umoa</translation>
+<translation id="917450738466192189">Palvelimen varmenne ei kelpaa.</translation>
+<translation id="9187827965378254003">Tällä hetkellä ei valitettavasti ole käytettävissä yhtään kokeilua.</translation>
<translation id="9207861905230894330">Artikkelin lisääminen epäonnistui.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">TYHJENNÄ LOMAKE</translation>
+<translation id="988159990683914416">Kehittäjän koontiversio</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_fil.xtb b/chromium/components/strings/components_strings_fil.xtb
index ba7cb61e582..80fa0ef222a 100644
--- a/chromium/components/strings/components_strings_fil.xtb
+++ b/chromium/components/strings/components_strings_fil.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="fil">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fil">
+<translation id="1032854598605920125">I-rotate pakanan</translation>
<translation id="1055184225775184556">&amp;I-undo ang Pagdagdag</translation>
<translation id="106701514854093668">Mga Bookmark sa Desktop</translation>
-<translation id="1103523840287552314">Palaging i-translate ang <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Pagkasyahin sa lapad</translation>
+<translation id="1103523840287552314">Palaging i-translate ang <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;I-undo ang pagbabago sa ayos</translation>
<translation id="111844081046043029">Sigurado ka ba na nais mong iwanan ang pahinang ito?</translation>
<translation id="112840717907525620">OK ang cache ng patakaran</translation>
<translation id="1132774398110320017">Mga setting ng Autofill ng Chrome...</translation>
-<translation id="1152921474424827756">Mag-access ng <ph name="BEGIN_LINK"/>naka-cache na kopya<ph name="END_LINK"/> ng <ph name="URL"/></translation>
+<translation id="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="1152921474424827756">Mag-access ng <ph name="BEGIN_LINK" />naka-cache na kopya<ph name="END_LINK" /> ng <ph name="URL" /></translation>
+<translation id="121201262018556460">Tinangka mong maabot ang <ph name="DOMAIN" />, ngunit nagpakita ang server ng isang certificate na naglalaman ng isang mahinang key. Maaaring sinira ng isang nang-aatake ang pribadong key, at ang server ay maaaring hindi ang server na iyong inaasahan (maaaring nakikipag-ugnay ka sa isang nang-aatake).</translation>
<translation id="1227224963052638717">Hindi kilalang patakaran</translation>
<translation id="1227633850867390598">Itago ang halaga</translation>
<translation id="1228893227497259893">Maling tagatukoy ng entity</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Domain ng pagpapatala:</translation>
<translation id="1344588688991793829">Mga setting ng Autofill ng Chromium...</translation>
<translation id="1426410128494586442">Oo</translation>
+<translation id="1430915738399379752">I-print</translation>
<translation id="1455235771979731432">Nagkaroon ng problema sa pag-verify ng iyong card. Tingnan ang koneksyon sa internet at subukang muli.</translation>
<translation id="1491151370853475546">I-reload ang Pahinang Ito</translation>
<translation id="1549470594296187301">Dapat naka-enable ang JavaScript upang magamit ang feature na ito.</translation>
-<translation id="1639239467298939599">Naglo-load</translation>
<translation id="1640180200866533862">Mga patakaran ng user</translation>
<translation id="1644184664548287040">Di-wasto ang configuration ng network at hindi maaaring i-import.</translation>
-<translation id="1693754753824026215">Isinasaad ng page sa <ph name="SITE"/> na:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; nag-expire na ang certificate ng seguridad nito kahapon. Maaaring resulta ito ng maling configuration o kaya ng isang attacker na humahadlang sa iyong koneksyon. Sa kasalukuyan, nakatakda ang orasan ng iyong computer sa <ph name="CURRENT_DATE" />. Mukha bang tama iyon? Kung hindi, dapat mong ayusin ang orasan ng iyong system at pagkatapos ay i-refresh ang page na ito.}one{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; nag-expire na ang certificate ng seguridad nito # araw na ang nakalipas. Maaaring resulta ito ng maling configuration o kaya ng isang attacker na humahadlang sa iyong koneksyon. Sa kasalukuyan, nakatakda ang orasan ng iyong computer sa <ph name="CURRENT_DATE" />. Mukha bang tama iyon? Kung hindi, dapat mong ayusin ang orasan ng iyong system at pagkatapos ay i-refresh ang page na ito.}other{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; nag-expire na ang certificate ng seguridad nito # na araw na ang nakalipas. Maaaring resulta ito ng maling configuration o kaya ng isang attacker na humahadlang sa iyong koneksyon. Sa kasalukuyan, nakatakda ang orasan ng iyong computer sa <ph name="CURRENT_DATE" />. Mukha bang tama iyon? Kung hindi, dapat mong ayusin ang orasan ng iyong system at pagkatapos ay i-refresh ang page na ito.}}</translation>
+<translation id="168841957122794586">Naglalaman ang server certificate ng isang mahinang cryptographic key.</translation>
+<translation id="1693754753824026215">Isinasaad ng page sa <ph name="SITE" /> na:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; hindi pinagkakatiwalaan ng operating system ng iyong device ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
<translation id="1821930232296380041">Di-wastong kahilingan o mga parameter ng kahilingan</translation>
-<translation id="1853748787962613237">Hindi naipakita ang artikulo.</translation>
<translation id="1871208020102129563">Nakatakda ang proxy upang gumamit ng mga hindi nababagong proxy server, hindi ng isang .pac script URL.</translation>
-<translation id="1875753206475436906">heuristic type: <ph name="HEURISTIC_TYPE"/>
- server type: <ph name="SERVER_TYPE"/>
- field signature: <ph name="FIELD_SIGNATURE"/>
- form signature: <ph name="FORM_SIGNATURE"/>
- experiment id: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Pumunta sa <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Mga Bookmark ng <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Pumunta sa <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Mga Bookmark ng <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Error sa serialization</translation>
+<translation id="1974060860693918893">Advanced</translation>
<translation id="2025186561304664664">Nakatakda sa awtomatikong naka-configure ang proxy.</translation>
<translation id="2025623846716345241">Kumpirmahin ang Pag-reload</translation>
-<translation id="2030481566774242610">Ang ibig mo bang sabihin ay <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Ang ibig mo bang sabihin ay <ph name="LINK" />?</translation>
<translation id="2053553514270667976">ZIP code</translation>
<translation id="20817612488360358">Itinatakda ang mga setting ng proxy ng system upang magamit ngunit tinutukoy rin ang isang tahasang configuration ng proxy.</translation>
<translation id="2094505752054353250">Maling pagtutugma sa domain</translation>
<translation id="2096368010154057602">Departamento</translation>
<translation id="2113977810652731515">Card</translation>
-<translation id="2114841414352855701">Binalewala dahil na-override ito ng <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Binalewala dahil na-override ito ng <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Mga Bookmark sa Mobile</translation>
+<translation id="2171101176734966184">Tinangka mong maabot ang <ph name="DOMAIN" />, ngunit nagpakita ang server ng certificate na nilagdaan gamit ang isang mahinang signature algorithm. Nangangahulugan ito na ang mga kredensyal na pangseguridad na ipinakita ng server ay maaaring pineke, at ang server ay maaaring hindi ang server na iyong inaasahan (maaaring nakikipag-ugnay ka sa isang nang-aatake).</translation>
<translation id="2181821976797666341">Mga Patakaran</translation>
<translation id="2212735316055980242">Hindi nahanap ang patakaran</translation>
<translation id="2213606439339815911">Kinukuha ang mga entry...</translation>
<translation id="225207911366869382">Hindi na gimagamit ang halagang ito para sa patakarang ito.</translation>
<translation id="2262243747453050782">Error sa HTTP</translation>
-<translation id="2270192940992995399">Hindi nahanap ang artikulo.</translation>
-<translation id="2328300916057834155">Binalewalang di-wastong bookmark sa index <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Mga Eksperimentong Hindi Available</translation>
+<translation id="229702904922032456">Nag-expire na ang isang pinagmulan o intermediate na certificate.</translation>
+<translation id="2328300916057834155">Binalewalang di-wastong bookmark sa index <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Iba pang mga bookmark</translation>
<translation id="2359808026110333948">Magpatuloy</translation>
<translation id="2367567093518048410">Antas</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="2396249848217231973">&amp;I-undo ang pagtanggal</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="2455981314101692989">Hindi pinagana ng webpage na ito ang awtomatikong pagpuno para sa form na ito.</translation>
<translation id="2479410451996844060">Di-wastong URL ng paghahanap.</translation>
+<translation id="2491120439723279231">Naglalaman ng mga error ang certificate ng server.</translation>
<translation id="2495083838625180221">Pang-parse ng JSON</translation>
<translation id="2498091847651709837">Mag-scan ng bagong card</translation>
<translation id="2556876185419854533">&amp;I-undo ang Pag-e-edit</translation>
-<translation id="2581221116934462656">Gusto mo bang mag-alok ang <ph name="PRODUCT_NAME"/> na i-translate ang mga page ng <ph name="LANGUAGE_NAME"/> mula sa site na ito sa susunod na pagkakataon?</translation>
+<translation id="2581221116934462656">Gusto mo bang mag-alok ang <ph name="PRODUCT_NAME" /> na i-translate ang mga page ng <ph name="LANGUAGE_NAME" /> mula sa site na ito sa susunod na pagkakataon?</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">Protektado ng password ang dokumentong ito. Mangyaring magpasok ng password.</translation>
+<translation id="2625385379895617796">Nauuna ang iyong orasan</translation>
<translation id="2639739919103226564">Katayuan:</translation>
+<translation id="2653659639078652383">Isumite</translation>
<translation id="2704283930420550640">Hindi tumutugma ang format sa halaga.</translation>
<translation id="2721148159707890343">Matagumpay ang kahilingan</translation>
+<translation id="2728127805433021124">Nilagdaan ang certificate ng server gamit ang mahinang algorithm ng lagda.</translation>
<translation id="2774256287122201187">Maaari ka nang magpatuloy. Kung magpapatuloy ka sa page, hindi na muling lalabas ang babalang ito sa loob ng limang minuto.</translation>
<translation id="277499241957683684">Nawawalang tala ng device</translation>
<translation id="2835170189407361413">I-clear ang form</translation>
-<translation id="2855922900409897335">I-verify ang iyong <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">I-verify ang iyong <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; nag-expire na ang certificate ng seguridad nito. Maaaring sanhi ito ng maling configuration o ng panghihimasok ng isang attacker sa iyong koneksyon. Kasalukuyang nakatakda ang orasan ng iyong computer sa <ph name="CURRENT_TIME" />. Mukha bang tama ito? Kung hindi, dapat mong iwasto ang orasan ng iyong system at pagkatapos ay i-refresh ang page na ito.</translation>
+<translation id="2922350208395188000">Hindi masuri ang certificate ng server.</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="2958431318199492670">Hindi sumusunod ang configuration ng network sa pamantayan ng ONC. Hindi maaaring i-import ang mga bahagi ng configuration.</translation>
<translation id="2972581237482394796">&amp;I-redo</translation>
-<translation id="3010559122411665027">Listahan ng entry na &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Listahan ng entry na "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Maling uri ng patakaran</translation>
<translation id="3105172416063519923">Asset ID:</translation>
<translation id="3145945101586104090">Nabigong i-decode ang tugon</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Pulo</translation>
<translation id="3219579145727097045">Ilagay ang petsa ng pag-expire at ang CVC na may 4 na digit mula sa harap ng iyong card</translation>
-<translation id="3228969707346345236">Nabigo ang pag-translate dahil nasa <ph name="LANGUAGE"/> na ang pahina.</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="3228969707346345236">Nabigo ang pag-translate dahil nasa <ph name="LANGUAGE" /> na ang pahina.</translation>
<translation id="3270847123878663523">&amp;I-undo ang Pagbabago sa Ayos</translation>
+<translation id="3286538390144397061">I-restart Ngayon</translation>
<translation id="333371639341676808">Iwasan ang pahinang ito mula sa paglikha ng karagdagang mga dialog.</translation>
-<translation id="3369366829301677151">I-update at i-verify ang iyong <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">mga setting</translation>
+<translation id="3369192424181595722">Error sa orasan</translation>
+<translation id="3369366829301677151">I-update at i-verify ang iyong <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Naalis sa pagkakaprobisyon</translation>
<translation id="3377188786107721145">Error sa pag-parse ng patakaran</translation>
<translation id="3380365263193509176">Hindi kilalang error</translation>
<translation id="3380864720620200369">Client ID:</translation>
<translation id="3427342743765426898">&amp;Gawing Muli ang Pag-e-edit</translation>
+<translation id="3435896845095436175">I-enable</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Kunin ang agwat:</translation>
+<translation id="3462200631372590220">Itago ang advanced</translation>
+<translation id="3528171143076753409">Hindi pinagkakatiwalaan ang certificate ng server.</translation>
<translation id="3542684924769048008">Gamitin ang password para sa:</translation>
<translation id="3583757800736429874">&amp;Gawing Muli ang Paglilipat</translation>
<translation id="3623476034248543066">Ipakita ang halaga</translation>
+<translation id="3648607100222897006">Maaaring mabago, masira, o mawala anumang oras ang mga pang-eksperimentong tampok na ito. Ganap kaming walang garantiya tungkol sa kung ano ang maaaring mangyari kung bubuksan mo ang isa sa mga eksperimentong ito, at maaari pang biglang masunog ang iyong browser. Walang halong pagbibiro, maaaring tanggalin ng iyong browser ang lahat ng iyong data, o maaaring makompromiso sa mga hindi inaasahang paraan ang iyong seguridad at privacy. Anumang mga eksperimento na iyong papaganahin ay mapapagana para sa lahat ng mga user sa browser na ito. Mangyaring maingat na magpatuloy.</translation>
<translation id="3650584904733503804">Matagumpay ang pagpapatunay</translation>
<translation id="370665806235115550">Kumakarga...</translation>
<translation id="3712624925041724820">Naubos na ang mga lisensya</translation>
<translation id="3739623965217189342">Link na kinopya mo</translation>
<translation id="375403751935624634">Nabigo ang translation dahil sa error sa server.</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>
<translation id="3885155851504623709">Parokya</translation>
<translation id="3934680773876859118">Nabigong i-load ang dokumentong PDF</translation>
<translation id="3963721102035795474">Reader Mode</translation>
<translation id="4030383055268325496">&amp;I-undo ang pagdagdag</translation>
-<translation id="4058922952496707368">Key &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">BABALA</translation>
+<translation id="4058922952496707368">Key "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Nakatakda ang configuration ng proxy upang gumamit ng isang .pac script URL, hindi ng mga hindi nababagong proxy server.</translation>
<translation id="409504436206021213">Huwag I-reload</translation>
<translation id="4103249731201008433">Di-wasto ang serial number ng device</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Maling lagda</translation>
<translation id="4269787794583293679">(Walang username)</translation>
<translation id="4300246636397505754">Mga suhestyon ng magulang</translation>
-<translation id="4372948949327679948">Inaasahang <ph name="VALUE_TYPE"/> na halaga.</translation>
+<translation id="4325863107915753736">Hindi nahanap ang artikulo</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="4394049700291259645">Huwag paganahin</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="443673843213245140">Hindi pinagana ang paggamit ng isang proxy ngunit tinutukoy ang isang tahasang configuration ng proxy.</translation>
-<translation id="4506176782989081258">Error sa pagpapatunay: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Error sa pagpapatunay: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Alisin ang address sa Chrome?</translation>
<translation id="4594403342090139922">&amp;I-undo ang Pagtanggal</translation>
<translation id="4607653538520819196">Ang page na ito ay hindi maaaring i-proxy ng Data Saver.</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="4726672564094551039">I-reload ang mga patakaran</translation>
+<translation id="4728558894243024398">Platform</translation>
+<translation id="4771973620359291008">Isang hindi alam na error ang nangyari.</translation>
<translation id="4800132727771399293">Tingnan ang iyong petsa ng pag-expire at CVC at subukang muli</translation>
<translation id="4813512666221746211">Error sa network</translation>
+<translation id="4816492930507672669">Pagkasyahin sa pahina</translation>
<translation id="4850886885716139402">View</translation>
-<translation id="4923417429809017348">Na-translate ang pahinang ito mula sa hindi kilalang wika patungo sa <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Na-translate ang pahinang ito mula sa hindi kilalang wika patungo sa <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Dapat na tukuyin.</translation>
<translation id="4968547170521245791">Hindi Mapo-proxy</translation>
-<translation id="498957508165411911">I-translate mula <ph name="ORIGINAL_LANGUAGE"/> patungong <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">I-translate mula <ph name="ORIGINAL_LANGUAGE" /> patungong <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Hindi maganda ang katayuan ng backing store</translation>
<translation id="5031870354684148875">Tungkol sa Google Translate</translation>
+<translation id="5045550434625856497">Hindi wastong password</translation>
+<translation id="5087286274860437796">Hindi angkop ang certificate ng server sa oras na ito.</translation>
<translation id="5089810972385038852">Estado</translation>
+<translation id="5094747076828555589">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; hindi pinagkakatiwalaan ng Chromium ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
<translation id="5095208057601539847">Probinsya</translation>
<translation id="5145883236150621069">May code ng error sa tugon sa patakaran</translation>
<translation id="5172758083709347301">Computer</translation>
-<translation id="5179510805599951267">Wala sa <ph name="ORIGINAL_LANGUAGE"/>? Iulat ang error na ito</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="5199729219167945352">Mga Eksperimento</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">Kumpirmahin ang Pag-nabiga</translation>
<translation id="5299298092464848405">Error sa pag-parse ng patakaran</translation>
+<translation id="5316812925700871227">I-rotate pakaliwa</translation>
<translation id="5317780077021120954">I-save</translation>
<translation id="536296301121032821">Nabigo i-load ang mga setting ng patakaran sa store</translation>
-<translation id="5439770059721715174">Error sa pagpapatunay ng schema sa &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Error sa pagpapatunay ng schema sa "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Maling timestamp ng patakaran</translation>
<translation id="5470861586879999274">&amp;Gawing muli ang pag-e-edit</translation>
<translation id="5509780412636533143">Mga pinamamahalaang bookmark</translation>
<translation id="5523118979700054094">Pangalan ng patakaran</translation>
<translation id="552553974213252141">Nakuha ba nang tama ang text?</translation>
<translation id="5540224163453853">Hindi mahanap ang hiniling na artikulo.</translation>
+<translation id="5556459405103347317">I-reload</translation>
<translation id="5565735124758917034">Aktibo</translation>
<translation id="560412284261940334">Hindi sinusuportahan ang pamamahala</translation>
<translation id="5629630648637658800">Nabigong i-load ang mga setting ng patakaran</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Kasalukuyang user</translation>
<translation id="5813119285467412249">&amp;Gawing Muli ang Pagdagdag</translation>
<translation id="5872918882028971132">Mga Suhestyon ng Magulang</translation>
-<translation id="587701087903783706">Isara ang view na pang-mobile</translation>
<translation id="59107663811261420">Ang ganitong uri ng card ay hindi sinusuportahan ng Google Payments para sa merchant na ito. Mangyaring pumili ng ibang card.</translation>
+<translation id="5975083100439434680">Mag-zoom out</translation>
<translation id="5989320800837274978">Hindi tunukoy ang alinman sa mga hindi nababagong proxy server o isang .pac script URL.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Isara</translation>
+<translation id="6060685159320643512">Mag-ingat, maaaring makahamak ang mga eksperimentong ito</translation>
+<translation id="6151417162996330722">Masyadong mahaba ang panahon ng pagkakaroon ng bisa ng certificate ng server.</translation>
<translation id="6154808779448689242">Hindi tumutugma ang ibinalik na token sa patakaran sa kasalukuyang token</translation>
<translation id="6165508094623778733">Matuto nang higit pa</translation>
<translation id="6259156558325130047">&amp;Gawing Muli ang Pagbabago sa Ayos</translation>
-<translation id="6263376278284652872">Mga bookmark ng <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Mga bookmark ng <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Postal code</translation>
<translation id="6337534724793800597">I-filter ang mga patakaran ayon sa pangalan</translation>
+<translation id="6387478394221739770">Interesado sa mga astig at bagong tampok sa Chrome? Subukan ang aming beta channel sa chrome.com/beta.</translation>
+<translation id="6426993025560594914">Available ang lahat ng eksperimento sa iyong platform!</translation>
<translation id="6445051938772793705">Bansa</translation>
<translation id="6458467102616083041">Binalewala dahil hindi pinagana ng patakaran ang default na paghahanap.</translation>
<translation id="647261751007945333">Mga patakaran sa device</translation>
<translation id="6512448926095770873">Iwanan ang Pahinang ito</translation>
<translation id="6529602333819889595">&amp;Gawing Muli ang Pagtanggal</translation>
<translation id="6550675742724504774">Mga Pagpipilian</translation>
-<translation id="6597614308054261376">Sinusubukan mong puntahan ang <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Ang page na ito ay hindi mapo-proxy ng Data Saver sa ngayon.</translation>
-<translation id="6628463337424475685">Paghahanap ng <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Sinusubukan mong puntahan ang <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Ang page na ito ay hindi mapo-proxy ng Data Saver sa ngayon.</translation>
+<translation id="6628463337424475685">Paghahanap ng <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Hindi na ginagamit ang patakarang ito.</translation>
<translation id="6646897916597483132">Ilagay ang CVC na may 4 na digit mula sa harap ng iyong card</translation>
+<translation id="674375294223700098">Hindi alam na error sa certificate ng server</translation>
<translation id="6753269504797312559">Halaga ng patakaran</translation>
<translation id="6831043979455480757">Isalin</translation>
<translation id="6839929833149231406">Lugar</translation>
<translation id="6874604403660855544">&amp;Gawing muli ang pagdagdag</translation>
<translation id="6891596781022320156">Hindi sinusuportahan ang antas ng patakaran.</translation>
<translation id="6915804003454593391">User:</translation>
+<translation id="6957887021205513506">Lumilitaw na isang pamamalsipika ang certificate ng server.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">Alerto ng JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Sinubukan mong puntahan ang <ph name="DOMAIN" />, ngunit nagpakita ang server ng certificate na masyadong mahaba ang panahon ng pagkakaroon ng bisa upang maging mapagkakatiwalaan.</translation>
<translation id="7087282848513945231">County</translation>
-<translation id="7108649287766967076">Nabigo ang pag-translate sa <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="7108649287766967076">Nabigo ang pag-translate sa <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="7139724024395191329">Emirate</translation>
+<translation id="7179921470347911571">Ilunsad Muli Ngayon</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="7186367841673660872">Naisalin ang pahinang ito mula sa<ph name="ORIGINAL_LANGUAGE" />sa<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Paghahanap <ph name="SITE_NAME"/> para sa <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Paghahanap <ph name="SITE_NAME" /> para sa <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Hindi makapagtatag ng pribadong koneksyon sa <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> dahil mali ang petsa at oras ng iyong computer (<ph name="DATE_AND_TIME" />).</translation>
<translation id="7275334191706090484">Mga Pinamamahalaang Bookmark</translation>
<translation id="7298195798382681320">Inirerekomenda</translation>
<translation id="7334320624316649418">&amp;Gawing muli ang pagbabago sa ayos</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Kinakailangan</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="7568593326407688803">Ang pahinang ito ay nasa<ph name="ORIGINAL_LANGUAGE"/>Gusto mong isalin ito?</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="7568593326407688803">Ang pahinang ito ay nasa<ph name="ORIGINAL_LANGUAGE" />Gusto mong isalin ito?</translation>
<translation id="7569952961197462199">Alisin ang credit card sa Chrome?</translation>
-<translation id="7600965453749440009">Huwag isalin kailanman ang <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Wala sa sakop ang halaga <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Lumabag ang certificate ng server sa limitasyon sa pangalan.</translation>
+<translation id="7600965453749440009">Huwag isalin kailanman ang <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Wala sa sakop ang halaga <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Interesado sa mga astig at bagong tampok sa Chrome? Subukan ang aming dev channel sa chrome.com/dev.</translation>
<translation id="7752995774971033316">Hindi pinamamahalaan</translation>
+<translation id="7761701407923456692">Hindi tumutugma sa URL ang certificate ng server.</translation>
<translation id="777702478322588152">Prefecture</translation>
<translation id="7791543448312431591">Magdagdag</translation>
<translation id="7805768142964895445">Katayuan</translation>
<translation id="7813600968533626083">Alisin ang suhestyon sa Chrome?</translation>
<translation id="7887683347370398519">Tingnan ang iyong CVC at subukang muli</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Wala pang bisa ang certificate ng server.</translation>
<translation id="7956713633345437162">Mga bookmark sa mobile</translation>
<translation id="7961015016161918242">Hindi Kailanman</translation>
<translation id="7977590112176369853">&lt;ilagay ang query&gt;</translation>
-<translation id="7983301409776629893">Palaging isalin ang <ph name="ORIGINAL_LANGUAGE"/> sa <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Palaging isalin ang <ph name="ORIGINAL_LANGUAGE" /> sa <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Mga bookmark sa desktop</translation>
<translation id="7995512525968007366">Hindi Tinukoy</translation>
-<translation id="8034522405403831421">Nasa <ph name="SOURCE_LANGUAGE"/> ang pahinang ito. Isalin ito sa <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Pag-override ng enterprise</translation>
+<translation id="8034522405403831421">Nasa <ph name="SOURCE_LANGUAGE" /> ang pahinang ito. Isalin ito sa <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Hindi natingnan ang artikulo.</translation>
<translation id="8091372947890762290">Nakabinbin sa server ang pag-activate</translation>
<translation id="8194797478851900357">&amp;I-undo ang Paglilipat</translation>
-<translation id="8201077131113104583">Di-wastong URL ng update para sa extension na may ID na &quot;<ph name="EXTENSION_ID"/>.&quot;</translation>
+<translation id="8201077131113104583">Di-wastong URL ng update para sa extension na may ID na "<ph name="EXTENSION_ID" />."</translation>
<translation id="8208216423136871611">Huwag mag-save</translation>
<translation id="8218327578424803826">Itinakdang Lokasyon:</translation>
<translation id="8249320324621329438">Huling kinuha:</translation>
+<translation id="8294431847097064396">Pinagmulan</translation>
<translation id="8308427013383895095">Nabigo ang translation dahil sa problema sa koneksyon sa network.</translation>
<translation id="8311778656528046050">Sigurado ka bang nais mong i-reload ang pahinang ito?</translation>
<translation id="8349305172487531364">Bookmarks bar</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Nalalapat sa</translation>
<translation id="8530504477309582336">Ang ganitong uri ng card ay hindi sinusuportahan ng Google Payments. Mangyaring pumili ng ibang card.</translation>
<translation id="8553075262323480129">Nabigo ang pag-translate dahil hindi matukoy ang wika ng pahina.</translation>
-<translation id="8571890674111243710">Tina-translate ang pahina sa <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Hindi makapagtatag ng pribadong koneksyon sa <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> dahil mali ang petsa at oras ng iyong device (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="8571890674111243710">Tina-translate ang pahina sa <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">I-reset ang lahat sa default</translation>
<translation id="8713130696108419660">Maling lagda ng inisyal</translation>
<translation id="8725066075913043281">Muling subukan</translation>
+<translation id="8738058698779197622">Upang makapagtatag ng secure na koneksyon, kailangang itakda nang tama ang iyong orasan. Ito ay dahil sa may-bisa lang ang mga certificate na ginagamit ng mga website upang tukuyin ang mga sarili ng mga ito sa loob ng mga partikular na tagal ng panahon. Dahil mali ang orasan ng iyong device, hindi ma-verify ng Chromium ang mga certificate na ito.</translation>
<translation id="8790007591277257123">&amp;Gawing muli ang pagtanggal</translation>
<translation id="8804164990146287819">Patakaran sa Privacy</translation>
+<translation id="8820817407110198400">Mga Bookmark</translation>
<translation id="8824019021993735287">Hindi na-verify ng Chrome ang iyong card sa oras na ito. Pakisubukang muli sa ibang pagkakataon.</translation>
<translation id="8834246243508017242">I-enable ang Autofill gamit ang Mga Contact…</translation>
<translation id="883848425547221593">Iba Pang Mga Bookmark</translation>
+<translation id="884923133447025588">Walang nahanap na mekanismo ng pagpapawalang-bisa.</translation>
<translation id="8866481888320382733">Error sa pag-parse ng mga setting ng patakaran</translation>
<translation id="8876793034577346603">Nabigong ma-parse ang configuration ng network.</translation>
<translation id="8891727572606052622">Di-wastong mode ng proxy.</translation>
-<translation id="8940229512486821554">Patakbuhin ang <ph name="EXTENSION_NAME"/> na command: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Paumanhin, hindi available ang eksperimentong ito sa iyong platform.</translation>
+<translation id="8903921497873541725">Mag-zoom in</translation>
+<translation id="8932102934695377596">Nahuhuli ang iyong orasan</translation>
+<translation id="8940229512486821554">Patakbuhin ang <ph name="EXTENSION_NAME" /> na command: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Nag-expire na ang certificate ng server.</translation>
<translation id="8988760548304185580">Ilagay ang petsa ng pag-expire at ang CVC na may 3 digit mula sa likod ng iyong card</translation>
-<translation id="9020542370529661692">Na-translate sa <ph name="TARGET_LANGUAGE"/> ang pahinang ito</translation>
+<translation id="901974403500617787">Ang may-ari lang ang maaaring magtakda ng mga flag na nalalapat sa buong system: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Na-translate sa <ph name="TARGET_LANGUAGE" /> ang pahinang ito</translation>
+<translation id="9049981332609050619">Tinangka mong maabot ang <ph name="DOMAIN" />, ngunit nagpakita ang server ng isang di-wastong certificate.</translation>
<translation id="9125941078353557812">Ilagay ang CVC na may 3 digit mula sa likod ng iyong card</translation>
<translation id="9137013805542155359">Ipakita ang orihinal</translation>
<translation id="9148507642005240123">&amp;I-undo ang pag-e-edit</translation>
<translation id="9154176715500758432">Manatili sa Pahinang ito</translation>
<translation id="9170848237812810038">&amp;I-undo</translation>
+<translation id="917450738466192189">Di-wastong certificate ng server.</translation>
+<translation id="9187827965378254003">Naku, mukhang walang kasalukuyang available na mga eksperimento.</translation>
<translation id="9207861905230894330">Hindi naidagdag ang artikulo.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">CLEAR FORM</translation>
+<translation id="988159990683914416">Bumuo ang Developer</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_fr.xtb b/chromium/components/strings/components_strings_fr.xtb
index f9709ade515..314f76a0cca 100644
--- a/chromium/components/strings/components_strings_fr.xtb
+++ b/chromium/components/strings/components_strings_fr.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="fr">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fr">
+<translation id="1032854598605920125">Faire pivoter vers la droite</translation>
<translation id="1055184225775184556">&amp;Annuler l'ajout</translation>
<translation id="106701514854093668">Favoris sur l'ordinateur</translation>
-<translation id="1103523840287552314">Toujours traduire les pages en <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Ajuster à la largeur</translation>
+<translation id="1103523840287552314">Toujours traduire les pages en <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Annuler la réorganisation</translation>
<translation id="111844081046043029">Voulez-vous vraiment quitter cette page ?</translation>
<translation id="112840717907525620">Cache de la règle valide.</translation>
<translation id="1132774398110320017">Paramètres de saisie automatique de Chrome…</translation>
-<translation id="1152921474424827756">Accédez à une <ph name="BEGIN_LINK"/>copie mise en cache<ph name="END_LINK"/> de <ph name="URL"/>.</translation>
+<translation id="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="1152921474424827756">Accédez à une <ph name="BEGIN_LINK" />copie mise en cache<ph name="END_LINK" /> de <ph name="URL" />.</translation>
+<translation id="121201262018556460">Vous avez tenté d'accéder à <ph name="DOMAIN" />, mais le serveur a présenté un certificat contenant une clé faible. Il est possible qu'un pirate ait compromis la clé privée. Il est donc possible que le serveur auquel vous avez accédé ne soit pas celui que vous croyez, et que vous soyez en train de communiquer avec un pirate informatique.</translation>
<translation id="1227224963052638717">Règle inconnue</translation>
<translation id="1227633850867390598">Masquer la valeur</translation>
<translation id="1228893227497259893">Identifiant d'entité incorrect.</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Domaine d'enregistrement :</translation>
<translation id="1344588688991793829">Paramètres de saisie automatique de Chromium…</translation>
<translation id="1426410128494586442">Oui</translation>
+<translation id="1430915738399379752">Imprimer</translation>
<translation id="1455235771979731432">Un problème est survenu lors de la validation de votre carte. Veuillez vérifier votre connexion Internet et réessayer.</translation>
<translation id="1491151370853475546">Actualiser cette page</translation>
<translation id="1549470594296187301">Vous devez activer JavaScript pour utiliser cette fonctionnalité.</translation>
-<translation id="1639239467298939599">Chargement en cours</translation>
<translation id="1640180200866533862">Règles relatives aux utilisateurs</translation>
<translation id="1644184664548287040">Impossible d'importer la configuration du réseau : elle n'est pas valide.</translation>
-<translation id="1693754753824026215">La page à l'adresse <ph name="SITE"/> indique :</translation>
+<translation id="1655462015569774233">{1,plural, =1{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité a expiré hier. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. L'horloge de votre ordinateur indique actuellement : <ph name="CURRENT_DATE" />. Cela vous semble-t-il correct ? Si ce n'est pas le cas, vous devez corriger l'horloge de votre système, puis actualiser la page.}one{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité a expiré il y a # jour. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. L'horloge de votre ordinateur indique actuellement : <ph name="CURRENT_DATE" />. Cela vous semble-t-il correct ? Si ce n'est pas le cas, vous devez corriger l'horloge de votre système, puis actualiser la page.}other{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité a expiré il y a # jours. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. L'horloge de votre ordinateur indique actuellement : <ph name="CURRENT_DATE" />. Cela vous semble-t-il correct ? Si ce n'est pas le cas, vous devez corriger l'horloge de votre système, puis actualiser la page.}}</translation>
+<translation id="168841957122794586">Le certificat du serveur contient une clé de chiffrement faible.</translation>
+<translation id="1693754753824026215">La page à l'adresse <ph name="SITE" /> indique :</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="1734864079702812349">American Express</translation>
+<translation id="1763864636252898013">Impossible de vérifier sur le serveur qu'il s'agit bien du domaine <ph name="DOMAIN" />, car son certificat de sécurité n'est pas considéré comme fiable par le système d'exploitation de votre appareil. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
<translation id="1821930232296380041">La demande ou ses paramètres ne sont pas valides.</translation>
-<translation id="1853748787962613237">Échec de l'affichage de l'article.</translation>
<translation id="1871208020102129563">Le proxy est configuré pour utiliser des serveurs proxy déterminés, pas une URL de script .pac.</translation>
-<translation id="1875753206475436906">type heuristique : <ph name="HEURISTIC_TYPE"/>
- type de serveur : <ph name="SERVER_TYPE"/>
- signature du champ : <ph name="FIELD_SIGNATURE"/>
- signature du formulaire : <ph name="FORM_SIGNATURE"/>
- identifiant de test : &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Accédez à <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Favoris du domaine <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Accédez à <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Favoris du domaine <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Erreur de sérialisation.</translation>
+<translation id="1974060860693918893">Paramètres avancés</translation>
<translation id="2025186561304664664">Le proxy est défini sur la configuration automatique.</translation>
<translation id="2025623846716345241">Confirmer l'actualisation</translation>
-<translation id="2030481566774242610">Essayez avec <ph name="LINK"/></translation>
+<translation id="2030481566774242610">Essayez avec <ph name="LINK" /></translation>
<translation id="2053553514270667976">Code postal</translation>
<translation id="20817612488360358">Les paramètres de proxy du système sont configurés pour être utilisés, mais une configuration de proxy explicite est également spécifiée.</translation>
<translation id="2094505752054353250">Le domaine ne correspond pas</translation>
<translation id="2096368010154057602">Département</translation>
<translation id="2113977810652731515">Carte</translation>
-<translation id="2114841414352855701">Ignorée parce que remplacée par <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Ignorée parce que remplacée par <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Favoris sur mobile</translation>
+<translation id="2171101176734966184">Vous avez tenté d'accéder à <ph name="DOMAIN" />, mais le serveur a présenté un certificat signé à l'aide d'un algorithme de signature faible. Il est possible que le certificat fourni par le serveur ait été falsifié. Il se peut donc que le serveur ne soit pas celui auquel vous souhaitez accéder, et qu'il s'agisse d'une tentative de piratage.</translation>
<translation id="2181821976797666341">Règles</translation>
<translation id="2212735316055980242">Règle introuvable.</translation>
<translation id="2213606439339815911">Obtention des entrées en cours…</translation>
<translation id="225207911366869382">Cette valeur n'est plus utilisée dans le cadre de cette règle.</translation>
<translation id="2262243747453050782">Erreur HTTP.</translation>
-<translation id="2270192940992995399">Échec de la détection de l'article.</translation>
-<translation id="2328300916057834155">Favori non valide ignoré (index <ph name="ENTRY_INDEX"/>)</translation>
+<translation id="2282872951544483773">Tests non disponibles.</translation>
+<translation id="229702904922032456">Un certificat racine ou intermédiaire a expiré.</translation>
+<translation id="2328300916057834155">Favori non valide ignoré (index <ph name="ENTRY_INDEX" />)</translation>
<translation id="2354001756790975382">Autres favoris</translation>
<translation id="2359808026110333948">Continuer</translation>
<translation id="2367567093518048410">Niveau</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="2396249848217231973">&amp;Annuler la suppression</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="2455981314101692989">Cette page Web a désactivé la saisie automatique dans ce formulaire.</translation>
<translation id="2479410451996844060">URL de recherche incorrecte</translation>
+<translation id="2491120439723279231">Le certificat du serveur contient des erreurs.</translation>
<translation id="2495083838625180221">Analyse de fichiers JSON</translation>
<translation id="2498091847651709837">Lire une nouvelle carte</translation>
<translation id="2556876185419854533">&amp;Annuler la modification</translation>
-<translation id="2581221116934462656">Souhaitez-vous que <ph name="PRODUCT_NAME"/> vous propose de traduire les pages en <ph name="LANGUAGE_NAME"/> de ce site lors de votre prochaine visite ?</translation>
+<translation id="2581221116934462656">Souhaitez-vous que <ph name="PRODUCT_NAME" /> vous propose de traduire les pages en <ph name="LANGUAGE_NAME" /> de ce site lors de votre prochaine visite ?</translation>
<translation id="2587841377698384444">ID de l'API d'annuaire :</translation>
<translation id="2597378329261239068">Ce document est protégé par mot de passe. Veuillez saisir ce dernier.</translation>
+<translation id="2625385379895617796">Votre horloge est en avance.</translation>
<translation id="2639739919103226564">État :</translation>
+<translation id="2653659639078652383">Valider</translation>
<translation id="2704283930420550640">La valeur ne respecte pas le format requis.</translation>
<translation id="2721148159707890343">Demande réussie.</translation>
+<translation id="2728127805433021124">Le certificat du serveur a été signé avec un algorithme de signature faible.</translation>
<translation id="2774256287122201187">Vous pouvez continuer. Si vous accédez à la page, cet avertissement ne s'affichera pas pendant cinq minutes.</translation>
<translation id="277499241957683684">Enregistrement de l'appareil manquant.</translation>
<translation id="2835170189407361413">Effacer le formulaire</translation>
-<translation id="2855922900409897335">Valider votre <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Valider votre <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Nous n'avons pas pu vérifier qu'il s'agissait du domaine <ph name="DOMAIN" />, car son certificat de sécurité a expiré. Cela peut être dû à une mauvaise configuration ou à une tentative d'interception de la connexion par un pirate informatique. L'horloge de votre ordinateur indique actuellement : <ph name="CURRENT_TIME" />. Cela vous semble-t-il correct ? Si ce n'est pas le cas, vous devez corriger l'horloge de votre système, puis réinitialiser la page.</translation>
+<translation id="2922350208395188000">Impossible de vérifier le certificat du serveur.</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="2958431318199492670">La configuration du réseau ne respecte pas les normes de l'ONC. Il est possible que des parties de la configuration ne soient pas importées.</translation>
<translation id="2972581237482394796">&amp;Rétablir</translation>
-<translation id="3010559122411665027">Entrée de la liste &quot;<ph name="ENTRY_INDEX"/>&quot; : <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Entrée de la liste "<ph name="ENTRY_INDEX" />" : <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Type de règle incorrect.</translation>
<translation id="3105172416063519923">ID d'élément :</translation>
<translation id="3145945101586104090">Échec du décodage de la réponse.</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Île</translation>
<translation id="3219579145727097045">Saisissez la date d'expiration et le code CVC à quatre chiffres figurant au recto de votre carte.</translation>
-<translation id="3228969707346345236">La traduction a échoué, car la page est déjà en <ph name="LANGUAGE"/>.</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="3228969707346345236">La traduction a échoué, car la page est déjà en <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Annuler la réorganisation</translation>
+<translation id="3286538390144397061">Redémarrer maintenant</translation>
<translation id="333371639341676808">Empêcher cette page de générer des boîtes de dialogue supplémentaires</translation>
-<translation id="3369366829301677151">Mettre à jour votre <ph name="CREDIT_CARD"/> et la valider</translation>
+<translation id="3340978935015468852">paramètres</translation>
+<translation id="3369192424181595722">Erreur de l'horloge</translation>
+<translation id="3369366829301677151">Mettre à jour votre <ph name="CREDIT_CARD" /> et la valider</translation>
<translation id="337363190475750230">Révoqué</translation>
<translation id="3377188786107721145">Erreur d'analyse de la règle.</translation>
<translation id="3380365263193509176">Erreur inconnue.</translation>
<translation id="3380864720620200369">ID client :</translation>
<translation id="3427342743765426898">&amp;Rétablir la modification</translation>
+<translation id="3435896845095436175">Activer</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Intervalle de récupération :</translation>
+<translation id="3462200631372590220">Masquer les paramètres avancés</translation>
+<translation id="3528171143076753409">Le certificat du serveur n'est pas approuvé.</translation>
<translation id="3542684924769048008">Utiliser un mot de passe pour :</translation>
<translation id="3583757800736429874">&amp;Rétablir le déplacement</translation>
<translation id="3623476034248543066">Afficher la valeur</translation>
+<translation id="3648607100222897006">Ces fonctionnalités expérimentales sont susceptibles d'être modifiées, de cesser de fonctionner ou de disparaître à tout moment. Nous ne garantissons en aucun cas les conséquences de l'activation de l'une d'entre elles. Il est même possible que votre navigateur s'auto-détruise ! Plus sérieusement, votre navigateur risque de supprimer toutes vos données. Votre sécurité et la confidentialité de vos données peuvent également être compromises de manière inattendue. Toute fonctionnalité expérimentale que vous activez le sera pour tous les utilisateurs de ce navigateur. Faites donc attention.</translation>
<translation id="3650584904733503804">Validation réussie.</translation>
<translation id="370665806235115550">Chargement...</translation>
<translation id="3712624925041724820">Licences épuisées.</translation>
<translation id="3739623965217189342">Lien copié</translation>
<translation id="375403751935624634">Échec de la traduction en raison d'une erreur de serveur</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>
<translation id="3885155851504623709">Paroisse</translation>
<translation id="3934680773876859118">Échec du chargement du document PDF</translation>
<translation id="3963721102035795474">Mode lecture</translation>
<translation id="4030383055268325496">&amp;Annuler l'ajout</translation>
-<translation id="4058922952496707368">Clé &quot;<ph name="SUBKEY"/>&quot; : <ph name="ERROR"/></translation>
+<translation id="404928562651467259">AVERTISSEMENT</translation>
+<translation id="4058922952496707368">Clé "<ph name="SUBKEY" />" : <ph name="ERROR" /></translation>
<translation id="4079302484614802869">La configuration du proxy est définie pour utiliser une URL de script .pac, et non pas des serveurs proxy déterminés.</translation>
<translation id="409504436206021213">Ne pas actualiser</translation>
<translation id="4103249731201008433">Le numéro de série de l'appareil n'est pas valide.</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Signature incorrecte.</translation>
<translation id="4269787794583293679">(aucun nom d'utilisateur)</translation>
<translation id="4300246636397505754">Suggestions des parents</translation>
-<translation id="4372948949327679948">Valeur attendue : <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Échec de la recherche de l'article.</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="4394049700291259645">Désactiver</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="443673843213245140">L'utilisation d'un proxy est désactivée, mais une configuration de proxy explicite est spécifiée.</translation>
-<translation id="4506176782989081258">Erreur de validation : <ph name="VALIDATION_ERROR"/>.</translation>
+<translation id="4506176782989081258">Erreur de validation : <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4587425331216688090">Supprimer l'adresse de Chrome ?</translation>
<translation id="4594403342090139922">&amp;Annuler la suppression</translation>
<translation id="4607653538520819196">Impossible d'envoyer cette page par proxy via l'économiseur de données</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="4726672564094551039">Actualiser les règles</translation>
+<translation id="4728558894243024398">Plate-forme</translation>
+<translation id="4771973620359291008">Une erreur inconnue s'est produite.</translation>
<translation id="4800132727771399293">Veuillez vérifier la date d'expiration et le code CVC, puis réessayez.</translation>
<translation id="4813512666221746211">Erreur réseau.</translation>
+<translation id="4816492930507672669">Ajuster à la page</translation>
<translation id="4850886885716139402">Afficher</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="4923417429809017348">Cette page rédigée dans une langue non identifiée a été traduite en <ph name="LANGUAGE_LANGUAGE" />.</translation>
<translation id="4926049483395192435">Doit être spécifié.</translation>
<translation id="4968547170521245791">Proxy impossible</translation>
-<translation id="498957508165411911">Traduire en <ph name="TARGET_LANGUAGE"/> cette page affichée en <ph name="ORIGINAL_LANGUAGE"/> ?</translation>
+<translation id="498957508165411911">Traduire en <ph name="TARGET_LANGUAGE" /> cette page affichée en <ph name="ORIGINAL_LANGUAGE" /> ?</translation>
<translation id="5019198164206649151">L'espace de stockage destiné à la sauvegarde est en mauvais état.</translation>
<translation id="5031870354684148875">À propos de Google Traduction</translation>
+<translation id="5045550434625856497">Mot de passe incorrect.</translation>
+<translation id="5087286274860437796">Le certificat actuel du serveur n'est pas valide.</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="5145883236150621069">Code d'erreur présent dans la réponse de la règle.</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="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="5199729219167945352">Prototypes</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">Confirmer la navigation</translation>
<translation id="5299298092464848405">Erreur d'analyse de la règle.</translation>
+<translation id="5316812925700871227">Faire pivoter vers la gauche</translation>
<translation id="5317780077021120954">Enregistrer</translation>
<translation id="536296301121032821">Échec du stockage des paramètres de la règle.</translation>
-<translation id="5439770059721715174">Erreur de validation du schéma au niveau de &quot;<ph name="ERROR_PATH"/>&quot; : <ph name="ERROR"/></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="5439770059721715174">Erreur de validation du schéma au niveau de "<ph name="ERROR_PATH" />" : <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Horodatage de la règle incorrect.</translation>
<translation id="5470861586879999274">&amp;Rétablir la modification</translation>
<translation id="5509780412636533143">Favoris gérés</translation>
<translation id="5523118979700054094">Nom de la règle</translation>
<translation id="552553974213252141">Le texte a-t-il été extrait correctement ?</translation>
<translation id="5540224163453853">Impossible de trouver l'article demandé.</translation>
+<translation id="5556459405103347317">Actualiser</translation>
<translation id="5565735124758917034">Actif</translation>
<translation id="560412284261940334">Gestion non acceptée.</translation>
<translation id="5629630648637658800">Échec du chargement des paramètres de la règle.</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Utilisateur actuel</translation>
<translation id="5813119285467412249">&amp;Rétablir l'ajout</translation>
<translation id="5872918882028971132">Suggestions des parents</translation>
-<translation id="587701087903783706">Fermer l'affichage adapté aux mobiles</translation>
<translation id="59107663811261420">Ce type de carte n'est pas compatible avec Google Payments pour ce marchand. Veuillez sélectionner une autre carte.</translation>
+<translation id="5975083100439434680">Zoom arrière</translation>
<translation id="5989320800837274978">Aucun serveur proxy déterminé ou URL de script .pac n'a été indiqué.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Fermer</translation>
+<translation id="6060685159320643512">Attention, ces fonctionnalités expérimentales peuvent mordre.</translation>
+<translation id="6151417162996330722">La durée de validité du certificat du serveur est trop longue.</translation>
<translation id="6154808779448689242">Le jeton de la règle renvoyé ne correspond pas au jeton actuel.</translation>
<translation id="6165508094623778733">En savoir plus</translation>
<translation id="6259156558325130047">&amp;Rétablir la réorganisation</translation>
-<translation id="6263376278284652872">Favoris de <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Favoris de <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Code postal</translation>
<translation id="6337534724793800597">Filtrer les règles par nom</translation>
+<translation id="6387478394221739770">Vous souhaitez bénéficier de nouvelles fonctionnalités Chrome passionnantes ? Essayez notre version bêta à l'adresse chrome.com/beta.</translation>
+<translation id="6426993025560594914">Tous les tests sont disponibles sur votre plate-forme.</translation>
<translation id="6445051938772793705">Pays</translation>
<translation id="6458467102616083041">Ignoré parce que la recherche par défaut est désactivée par une règle.</translation>
<translation id="647261751007945333">Règles relatives aux appareils</translation>
<translation id="6512448926095770873">Quitter cette page</translation>
<translation id="6529602333819889595">&amp;Rétablir la suppression</translation>
<translation id="6550675742724504774">Options</translation>
-<translation id="6597614308054261376">Vous essayez d'accéder à <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Cette page ne peut pas être envoyée par proxy via l'économiseur de données pour le moment.</translation>
-<translation id="6628463337424475685">Recherche <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Vous essayez d'accéder à <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Cette page ne peut pas être envoyée par proxy via l'économiseur de données pour le moment.</translation>
+<translation id="6628463337424475685">Recherche <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Cette règle est obsolète.</translation>
<translation id="6646897916597483132">Saisissez le code CVC à quatre chiffres indiqué au recto de votre carte.</translation>
+<translation id="674375294223700098">Erreur inconnue liée au certificat du serveur.</translation>
<translation id="6753269504797312559">Valeur de la règle</translation>
<translation id="6831043979455480757">Traduire</translation>
<translation id="6839929833149231406">Région</translation>
<translation id="6874604403660855544">&amp;Rétablir l'ajout</translation>
<translation id="6891596781022320156">Le niveau de la règle n'est pas accepté.</translation>
<translation id="6915804003454593391">Utilisateur :</translation>
+<translation id="6957887021205513506">Le certificat du serveur semble être contrefait.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">Alerte JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Vous avez essayé d'accéder à <ph name="DOMAIN" />, mais la durée de validité du certificat du serveur est trop longue pour être fiable.</translation>
<translation id="7087282848513945231">Comté</translation>
-<translation id="7108649287766967076">Échec de la traduction en <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="7108649287766967076">Échec de la traduction en <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="7139724024395191329">Émirat</translation>
+<translation id="7179921470347911571">Relancer maintenant</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="7186367841673660872">Cette page en<ph name="ORIGINAL_LANGUAGE" />a été traduite en<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Rechercher <ph name="SEARCH_TERMS"/> sur <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Rechercher <ph name="SEARCH_TERMS" /> sur <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">Impossible d'établir une connexion privée à <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> : la date et l'heure de votre ordinateur (<ph name="DATE_AND_TIME" />) sont incorrectes.</translation>
<translation id="7275334191706090484">Favoris gérés</translation>
<translation id="7298195798382681320">Recommandé</translation>
<translation id="7334320624316649418">&amp;Rétablir la réorganisation</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obligatoire</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="7568593326407688803">Cette page est en<ph name="ORIGINAL_LANGUAGE"/>Voulez-vous la traduire ?</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="7568593326407688803">Cette page est en<ph name="ORIGINAL_LANGUAGE" />Voulez-vous la traduire ?</translation>
<translation id="7569952961197462199">Supprimer les données de carte de paiement de Chrome ?</translation>
-<translation id="7600965453749440009">Ne jamais traduire les pages rédigées en <ph name="LANGUAGE"/> </translation>
-<translation id="7610193165460212391">La valeur <ph name="VALUE"/> est hors limites.</translation>
+<translation id="7592362899630581445">Le certificat du serveur ne respecte pas les restrictions de noms.</translation>
+<translation id="7600965453749440009">Ne jamais traduire les pages rédigées en <ph name="LANGUAGE" /> </translation>
+<translation id="7610193165460212391">La valeur <ph name="VALUE" /> est hors limites.</translation>
+<translation id="7674629440242451245">Vous souhaitez bénéficier de nouvelles fonctionnalités Chrome passionnantes ? Essayez notre version en développement à l'adresse chrome.com/dev.</translation>
<translation id="7752995774971033316">Non géré</translation>
+<translation id="7761701407923456692">Le certificat du serveur ne correspond pas à l'URL.</translation>
<translation id="777702478322588152">Préfecture</translation>
<translation id="7791543448312431591">Ajouter</translation>
<translation id="7805768142964895445">État</translation>
<translation id="7813600968533626083">Supprimer la suggestion de saisie de formulaire de Chrome ?</translation>
<translation id="7887683347370398519">Veuillez vérifier votre code CVC et réessayer.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Le certificat du serveur n'est pas encore valide.</translation>
<translation id="7956713633345437162">Favoris sur mobile</translation>
<translation id="7961015016161918242">Jamais</translation>
<translation id="7977590112176369853">&lt;saisir une requête&gt;</translation>
-<translation id="7983301409776629893">Toujours traduire en <ph name="TARGET_LANGUAGE"/> les pages en <ph name="ORIGINAL_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Toujours traduire en <ph name="TARGET_LANGUAGE" /> les pages en <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7988324688042446538">Favoris sur l'ordinateur</translation>
<translation id="7995512525968007366">Non spécifié</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="8003882219468422867">Règle d'entreprise prioritaire</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="8088680233425245692">Échec de l'affichage de l'article.</translation>
<translation id="8091372947890762290">Activation en attente sur le serveur.</translation>
<translation id="8194797478851900357">&amp;Annuler le déplacement</translation>
-<translation id="8201077131113104583">URL de mise à jour non valide pour l'extension associée à l'identifiant &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">URL de mise à jour non valide pour l'extension associée à l'identifiant "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Ne pas enregistrer</translation>
<translation id="8218327578424803826">Position attribuée :</translation>
<translation id="8249320324621329438">Dernière récupération :</translation>
+<translation id="8294431847097064396">Source</translation>
<translation id="8308427013383895095">Échec de la traduction en raison d'un problème de connexion réseau</translation>
<translation id="8311778656528046050">Voulez-vous vraiment actualiser cette page ?</translation>
<translation id="8349305172487531364">Barre de favoris</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">S'applique à</translation>
<translation id="8530504477309582336">Ce type de carte n'est pas compatible avec Google Payments. Veuillez sélectionner une autre carte.</translation>
<translation id="8553075262323480129">La traduction a échoué, car nous n'avons pas pu déterminer la langue de la page.</translation>
-<translation id="8571890674111243710">Traduction de la page en <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Impossible d'établir une connexion privée à <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> : la date et l'heure de votre appareil (<ph name="DATE_AND_TIME" />) sont incorrectes.</translation>
+<translation id="8571890674111243710">Traduction de la page en <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Rétablir tous les tests par défaut</translation>
<translation id="8713130696108419660">Signature initiale incorrecte.</translation>
<translation id="8725066075913043281">Réessayer</translation>
+<translation id="8738058698779197622">Afin d'établir une connexion sécurisée, votre horloge doit être réglée correctement. Les certificats permettant aux sites Web de s'identifier sont en effet valides pendant une période précise. Si l'horloge de votre appareil est incorrecte, Chromium n'est pas en mesure de vérifier la validité des certificats.</translation>
<translation id="8790007591277257123">&amp;Rétablir la suppression</translation>
<translation id="8804164990146287819">Règles de confidentialité</translation>
+<translation id="8820817407110198400">Favoris</translation>
<translation id="8824019021993735287">Impossible de valider votre carte pour le moment. Veuillez réessayer ultérieurement.</translation>
<translation id="8834246243508017242">Activer la saisie automatique à l'aide de la fonctionnalité Contacts</translation>
<translation id="883848425547221593">Autres favoris</translation>
+<translation id="884923133447025588">Aucun système de révocation trouvé</translation>
<translation id="8866481888320382733">Erreur d'analyse des paramètres de la règle.</translation>
<translation id="8876793034577346603">Échec de l'analyse de la configuration du réseau.</translation>
<translation id="8891727572606052622">Mode proxy non valide.</translation>
-<translation id="8940229512486821554">Exécuter la commande <ph name="EXTENSION_NAME"/> : <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Désolé, cette fonctionnalité expérimentale n'est pas disponible pour votre plate-forme.</translation>
+<translation id="8903921497873541725">Zoom avant</translation>
+<translation id="8932102934695377596">Votre horloge est en retard</translation>
+<translation id="8940229512486821554">Exécuter la commande <ph name="EXTENSION_NAME" /> : <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Le certificat du serveur a expiré.</translation>
<translation id="8988760548304185580">Saisissez la date d'expiration et le code CVC à trois chiffres figurant au dos de votre carte.</translation>
-<translation id="9020542370529661692">Cette page a été traduite en <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="901974403500617787">Seul le propriétaire suivant peut définir les options qui s'appliquent à tout le système : <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Cette page a été traduite en <ph name="TARGET_LANGUAGE" />.</translation>
+<translation id="9049981332609050619">Vous avez tenté de contacter <ph name="DOMAIN" />, mais le certificat présenté par le serveur est incorrect.</translation>
<translation id="9125941078353557812">Saisissez le code CVC à trois chiffres indiqué au dos de votre carte.</translation>
<translation id="9137013805542155359">Afficher l'original</translation>
<translation id="9148507642005240123">&amp;Annuler la modification</translation>
<translation id="9154176715500758432">Rester sur cette page</translation>
<translation id="9170848237812810038">Ann&amp;uler</translation>
+<translation id="917450738466192189">Le certificat du serveur n'est pas valide.</translation>
+<translation id="9187827965378254003">Vraiment désolé, aucun prototype n'est disponible pour le moment.</translation>
<translation id="9207861905230894330">Échec de l'ajout de l'article.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">EFFACER LE FORMULAIRE</translation>
+<translation id="988159990683914416">Build de développement</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_gu.xtb b/chromium/components/strings/components_strings_gu.xtb
index 5d838038fd8..501c4a657ed 100644
--- a/chromium/components/strings/components_strings_gu.xtb
+++ b/chromium/components/strings/components_strings_gu.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="gu">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="gu">
+<translation id="1032854598605920125">ઘડિયાળની દિશામાં ફેરવો</translation>
<translation id="1055184225775184556">&amp;ઉમેરવું પૂર્વવત્ કરો</translation>
<translation id="106701514854093668">ડેસ્કટૉપ બુકમાર્ક્સ</translation>
-<translation id="1103523840287552314"><ph name="LANGUAGE"/> નો હંમેશાં અનુવાદ કરો</translation>
+<translation id="1080116354587839789">પહોળાઈ પ્રમાણે ફિટ કરો</translation>
+<translation id="1103523840287552314"><ph name="LANGUAGE" /> નો હંમેશાં અનુવાદ કરો</translation>
<translation id="1113869188872983271">&amp;પુનઃક્રમાંકિત કરવું પૂર્વવત્ કરો</translation>
<translation id="111844081046043029">શું તમે ખરેખર આ પૃષ્ઠ છોડવા માંગો છો?</translation>
<translation id="112840717907525620">નીતિ કેશ ઑકે</translation>
<translation id="1132774398110320017">Chrome સ્વતઃભરણ સેટિંગ્સ...</translation>
-<translation id="1152921474424827756"><ph name="URL"/> ની <ph name="BEGIN_LINK"/>કેશ કરેલ કૉપિ<ph name="END_LINK"/> ઍક્સેસ કરો</translation>
+<translation id="1150979032973867961">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર તમારા કમ્પ્યુટરની ઑપરેટિંગ સિસ્ટમ દ્વારા વિશ્વસનીય નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
+<translation id="1152921474424827756"><ph name="URL" /> ની <ph name="BEGIN_LINK" />કેશ કરેલ કૉપિ<ph name="END_LINK" /> ઍક્સેસ કરો</translation>
+<translation id="121201262018556460">તમે <ph name="DOMAIN" /> સુધી પહોંચવાનો પ્રયાસ કર્યો, પણ પ્રમાણપત્ર રજૂ કરતા સર્વર પાસે નબળી કી છે. હુમલાખોરે ખાનગી કી તોડી હોઈ શકે છે, અને બને કે સર્વર તમારું અપેક્ષિત સર્વર ન હોય (તમે કોઈ હુમલાખોર સાથે વાર્તાલાપ કરી રહ્યાં હોઈ શકો છો).</translation>
<translation id="1227224963052638717">અજ્ઞાત નીતિ.</translation>
<translation id="1227633850867390598">મૂલ્ય છુપાવો</translation>
<translation id="1228893227497259893">ખોટો અસ્તિત્વ ઓળખકર્તા</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">નોંધણી ડોમેન:</translation>
<translation id="1344588688991793829">Chromium સ્વતઃભરણ સેટિંગ્સ...</translation>
<translation id="1426410128494586442">હા</translation>
+<translation id="1430915738399379752">છાપો</translation>
<translation id="1455235771979731432">તમારું કાર્ડ ચકાસવામાં એક સમસ્યા આવી હતી. તમારું ઇન્ટરનેટ કનેક્શન તપાસો અને ફરીથી પ્રયાસ કરો.</translation>
<translation id="1491151370853475546">આ પૃષ્ઠને ફરીથી લોડ કરો</translation>
<translation id="1549470594296187301">આ સુવિધાનો ઉપયોગ કરવા માટે JavaScript સક્ષમ કરેલ હોવી આવશ્યક છે.</translation>
-<translation id="1639239467298939599">લોડ કરી રહ્યું છે</translation>
<translation id="1640180200866533862">વપરાશકર્તા નીતિઓ</translation>
<translation id="1644184664548287040">નેટવર્ક ગોઠવણી અમાન્ય છે અને આયાત કરી શકાઇ નથી.</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> પરનું પૃષ્ઠ કહે છે:</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="168841957122794586">સર્વર પ્રમાણપત્ર એક નબળી ક્રિપ્ટોગ્રાફિક કી ધરાવે છે.</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> પરનું પૃષ્ઠ કહે છે:</translation>
+<translation id="1706954506755087368">{1,plural, =1{આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર આવતીકાલથી માનવામાં આવે છે તે પ્રમાણે છે. આ કોઇ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઇ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.}one{આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર માનવામાં આવે છે તે પ્રમાણે ભવિષ્યમાં # દિવસથી છે. આ કોઇ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઇ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.}other{આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર માનવામાં આવે છે તે પ્રમાણે ભવિષ્યમાં # દિવસથી છે. આ કોઇ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઇ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર તમારા ઉપકરણની ઑપરેટિંગ સિસ્ટમ દ્વારા વિશ્વસનીય નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
<translation id="1821930232296380041">અમાન્ય વિનંતી અથવા વિનંતી પરિમાણો</translation>
-<translation id="1853748787962613237">લેખ પ્રદર્શિત કરવામાં નિષ્ફળ થયાં.</translation>
<translation id="1871208020102129563">પ્રોક્સી નિયત કરેલા પ્રોક્સી સર્વરનો ઉપયોગ કરવા માટે સેટ કરેલી છે, .pac સ્ક્રિપ્ટ URL નથી.</translation>
-<translation id="1875753206475436906">સંશોધનાત્મક પ્રકાર: <ph name="HEURISTIC_TYPE"/>
- સર્વર પ્રકાર: <ph name="SERVER_TYPE"/>
- ફીલ્ડ સહી: <ph name="FIELD_SIGNATURE"/>
- ફોર્મ સહી: <ph name="FORM_SIGNATURE"/>
- પ્રાયોગિક id: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158"><ph name="LINK"/> પર જાઓ</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> બુકમાર્ક્સ</translation>
+<translation id="194030505837763158"><ph name="LINK" /> પર જાઓ</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> બુકમાર્ક્સ</translation>
<translation id="1973335181906896915">અનુક્રમાંકન ભૂલ</translation>
+<translation id="1974060860693918893">વિગતવાર</translation>
<translation id="2025186561304664664">પ્રોક્સી સ્વતઃ ગોઠવાયેલી પર સેટ છે.</translation>
<translation id="2025623846716345241">ફરીથી લોડ કરવાની પુષ્ટિ કરો</translation>
-<translation id="2030481566774242610">શું તમારો અર્થ <ph name="LINK"/> છે?</translation>
+<translation id="2030481566774242610">શું તમારો અર્થ <ph name="LINK" /> છે?</translation>
<translation id="2053553514270667976">પિન કોડ</translation>
<translation id="20817612488360358">સિસ્ટમ પ્રોક્સી સેટિંગ્સ ઉપયોગમાં લેવા માટે સેટ છે પણ એક સ્પષ્ટ પ્રોક્સી ગોઠવણી પણ ઉલ્લેખિત કરેલી છે.</translation>
<translation id="2094505752054353250">ડોમેન મેળ ખાતું નથી</translation>
<translation id="2096368010154057602">વિભાગ</translation>
<translation id="2113977810652731515">કાર્ડ</translation>
-<translation id="2114841414352855701">અવગણ્યું કારણ કે તે <ph name="POLICY_NAME"/> દ્વારા ઓવરરાઇડ થયું હતું.</translation>
+<translation id="2114841414352855701">અવગણ્યું કારણ કે તે <ph name="POLICY_NAME" /> દ્વારા ઓવરરાઇડ થયું હતું.</translation>
+<translation id="2128531968068887769">મૂળ ક્લાઇન્ટ</translation>
<translation id="213826338245044447">મોબાઇલ બુકમાર્ક્સ</translation>
+<translation id="2171101176734966184">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પ્રયાસ કર્યો, પરંતુ સર્વરે નબળા હસ્તાક્ષર અલ્ગોરિધમનો ઉપયોગ કરીને હસ્તાક્ષરિત કરેલું પ્રમાણપત્ર પ્રસ્તુત કર્યું. આનો અર્થ એ છે કે સર્વરે પ્રસ્તુત કરેલા સુરક્ષા પ્રમાણપત્રો બનાવટી હોઈ શકે છે અને તે સર્વર તમારું અપેક્ષિત સર્વર (તમે કોઈ હુમલાખોર સાથે વાર્તાલાપ કરી શકો છો) ન પણ હોય.</translation>
<translation id="2181821976797666341">નીતિઓ</translation>
<translation id="2212735316055980242">નીતિ મળી નથી</translation>
<translation id="2213606439339815911">પ્રવિષ્ટિઓનું આનયન કરી રહ્યાં છે...</translation>
<translation id="225207911366869382">આ નીતિ માટે આ મૂલ્યને નાપસંદ કરેલું છે.</translation>
<translation id="2262243747453050782">HTTP ભૂલ</translation>
-<translation id="2270192940992995399">લેખ શોધવામાં નિષ્ફળ થયાં.</translation>
-<translation id="2328300916057834155"><ph name="ENTRY_INDEX"/> અનુક્રમણિકા પર અમાન્ય બુકમાર્ક અવગ્ણ્યો</translation>
+<translation id="2282872951544483773">અનુપલબ્ધ પ્રયોગો</translation>
+<translation id="229702904922032456">રૂટ અથવા મધ્યવર્તી પ્રમાણપત્રની સમય-સીમા સમાપ્ત થઈ.</translation>
+<translation id="2328300916057834155"><ph name="ENTRY_INDEX" /> અનુક્રમણિકા પર અમાન્ય બુકમાર્ક અવગ્ણ્યો</translation>
<translation id="2354001756790975382">અન્ય બુકમાર્ક્સ</translation>
<translation id="2359808026110333948">ચાલુ રાખો</translation>
<translation id="2367567093518048410">સ્તર</translation>
+<translation id="2384307209577226199">એન્ટરપ્રાઇઝ ડિફોલ્ટ</translation>
+<translation id="2386255080630008482">સર્વરનું પ્રમાણપત્ર રદ કરવામાં આવ્યું છે.</translation>
<translation id="2392959068659972793">કોઈ કિંમત સેટ નહીં સાથે નીતિઓ બતાવો</translation>
<translation id="2396249848217231973">&amp;કાઢી નાખવું પૂર્વવત્‌ કરો</translation>
+<translation id="2413528052993050574">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર રદબાતલ થયું હશે. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
<translation id="2455981314101692989">આ વેબપૃષ્ઠે આ ફોર્મનું આપમેળે ભરણ અક્ષમ કર્યું છે.</translation>
<translation id="2479410451996844060">અમાન્ય શોધ URL.</translation>
+<translation id="2491120439723279231">સર્વરના પ્રમાણપત્રમાં ભૂલો છે.</translation>
<translation id="2495083838625180221">JSON વિશ્લેશક</translation>
<translation id="2498091847651709837">નવું કાર્ડ સ્કૅન કરો</translation>
<translation id="2556876185419854533">&amp;સંપાદિત કરવું પૂર્વવત્‌ કરો</translation>
-<translation id="2581221116934462656">શું તમે <ph name="PRODUCT_NAME"/> ને આ સાઇટથી આગલી વખતે <ph name="LANGUAGE_NAME"/> પૃષ્ઠોમાં અનુવાદની ઓફર કરવા માગો છો?</translation>
+<translation id="2581221116934462656">શું તમે <ph name="PRODUCT_NAME" /> ને આ સાઇટથી આગલી વખતે <ph name="LANGUAGE_NAME" /> પૃષ્ઠોમાં અનુવાદની ઓફર કરવા માગો છો?</translation>
<translation id="2587841377698384444">નિર્દેશિકા API ID:</translation>
<translation id="2597378329261239068">આ દસ્તાવેજ પાસવર્ડ સુરક્ષિત છે. કૃપા કરીને પાસવર્ડ દાખલ કરો.</translation>
+<translation id="2625385379895617796">તમારી ઘડિયાળ આગળ છે</translation>
<translation id="2639739919103226564">સ્થિતિ:</translation>
+<translation id="2653659639078652383">સબમિટ કરો</translation>
<translation id="2704283930420550640">મૂલ્ય ફોર્મેટથી મેળ ખાતું નથી.</translation>
<translation id="2721148159707890343">વિનંતી સફળ થઇ</translation>
+<translation id="2728127805433021124">સર્વરનું પ્રમાણપત્ર એક નબળા હસ્તાક્ષર અલ્ગોરિધમનો ઉપયોગ કરીને હસ્તાક્ષરિત કરેલું છે.</translation>
<translation id="2774256287122201187">તમે ચાલુ રાખી શકો છો. જો તમે પૃષ્ઠ પર ચાલુ રહો છો, તો આ ચેતવણી પાંચ મિનિટ માટે ફરીથી દેખાશે નહીં.</translation>
<translation id="277499241957683684">ઉપકરણ રેકોર્ડ ખૂટે છે</translation>
<translation id="2835170189407361413">ફોર્મ સાફ કરો</translation>
-<translation id="2855922900409897335">તમારું <ph name="CREDIT_CARD"/> ચકાસો</translation>
+<translation id="2855922900409897335">તમારું <ph name="CREDIT_CARD" /> ચકાસો</translation>
+<translation id="2915500479781995473">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેના સુરક્ષા પ્રમાણપત્રની સમયસીમા સમાપ્ત થઈ છે. આ કોઈ ગેરગોઠવણના કારણે થયું છે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે. તમારા કમ્પ્યુટરની ઘડિયાળ હાલમાં <ph name="CURRENT_TIME" /> પર સેટ છે. શું તે બરાબર છે? જો નહીં, તો તમારે તમારા સિસ્ટમની ઘડિયાળને ઠીક કરવી જોઈએ અને તે પછી આ પૃષ્ઠને ફરી તાજું કરો.</translation>
+<translation id="2922350208395188000">સર્વરનું પ્રમાણપત્ર તપાસી શકાતું નથી.</translation>
+<translation id="2941952326391522266">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર <ph name="DOMAIN2" /> નું છે. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
<translation id="2958431318199492670">નેટવર્ક ગોઠવણી ONC માનકનું પાલન કરતી નથી. ગોઠવણીના ભાગો આયાત કરી શકાશે નહીં.</translation>
<translation id="2972581237482394796">&amp;ફરી કરો</translation>
-<translation id="3010559122411665027">&quot;<ph name="ENTRY_INDEX"/>&quot; એન્ટ્રીને સૂચિબદ્ધ કરો: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">"<ph name="ENTRY_INDEX" />" એન્ટ્રીને સૂચિબદ્ધ કરો: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">ખોટો નીતિ પ્રકાર</translation>
<translation id="3105172416063519923">સંપત્તિ ID:</translation>
<translation id="3145945101586104090">પ્રતિક્રિયા ડિકોડ કરવી નિષ્ફળ થઇ</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">આઇલેન્ડ</translation>
<translation id="3219579145727097045">તમારા કાર્ડની આગળની બાજુ પરથી સમાપ્તિ તારીખ અને 4-અંકનો CVC દાખલ કરો</translation>
-<translation id="3228969707346345236">ભાષાંતર નિષ્ફળ રહ્યું કારણ કે પૃષ્ઠ પહેલાથી જ <ph name="LANGUAGE"/> માં છે.</translation>
+<translation id="3225919329040284222">સર્વર એક પ્રમાણપત્ર પ્રસ્તુત કરે છે જે બિલ્ટ-ઇન અપેક્ષાઓ સાથે મેળ ખાતું નથી. આ અપેક્ષાઓમાં તમને સુરક્ષિત રાખવા માટે અમુક ચોક્કસ, ઉચ્ચ-સુરક્ષા વેબસાઇટ્સનો સમાવેશ થાય છે.</translation>
+<translation id="3228969707346345236">ભાષાંતર નિષ્ફળ રહ્યું કારણ કે પૃષ્ઠ પહેલાથી જ <ph name="LANGUAGE" /> માં છે.</translation>
<translation id="3270847123878663523">&amp;પુનઃક્રમાંકિત કરવું પૂર્વવત્ કરો</translation>
+<translation id="3286538390144397061">હવે ફરીથી પ્રારંભ કરો</translation>
<translation id="333371639341676808">આ પૃષ્ઠને વધારાનાં સંવાદો બનાવવાથી રોકો.</translation>
-<translation id="3369366829301677151">તમારું <ph name="CREDIT_CARD"/> અપડેટ કરો અને ચકાસો</translation>
+<translation id="3340978935015468852">સેટિંગ્સ</translation>
+<translation id="3369192424181595722">ઘડિયાળ ભૂલ</translation>
+<translation id="3369366829301677151">તમારું <ph name="CREDIT_CARD" /> અપડેટ કરો અને ચકાસો</translation>
<translation id="337363190475750230">જોગવાઈ દૂર કરી</translation>
<translation id="3377188786107721145">નીતિ વિશ્લેષણ ભૂલ</translation>
<translation id="3380365263193509176">અજ્ઞાત ભૂલ</translation>
<translation id="3380864720620200369">ક્લાઇન્ટ ID:</translation>
<translation id="3427342743765426898">&amp;સંપાદિત કરવું ફરી કરો</translation>
+<translation id="3435896845095436175">સક્ષમ કરો</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">આનયન અંતરાલ:</translation>
+<translation id="3462200631372590220">વિગતવાર છુપાવો</translation>
+<translation id="3528171143076753409">સર્વરનું પ્રમાણપત્ર વિશ્વસનીય નથી.</translation>
<translation id="3542684924769048008">આ માટે પાસવર્ડનો ઉપયોગ કરો:</translation>
<translation id="3583757800736429874">&amp;ખસેડવું ફરી કરો</translation>
<translation id="3623476034248543066">કિંમત બતાવો</translation>
+<translation id="3648607100222897006">આ પ્રાયોગિક સુવિધાઓ કોઈપણ સમયે બદલાઈ, ભંગ અથવા અદૃશ્ય થઈ શકે છે. જો તમે આમાંના કોઈ એક પ્રયોગને ચાલુ કરો છો તો તેનું શું થશે તેની અમે કોઈ ગેરેંટી આપી શકતા નથી, બને કે તમારું બ્રાઉઝર પણ ભડકી ઉઠે. તમારું બ્રાઉઝર તમારા ડેટાને કાઢી નાખી શકે છે, અથવા તમારી સુરક્ષા અને ગોપનીયતા સાથે અનપેક્ષિત રીતે ચેડા થઈ શકે છે. તમે જે પ્રયોગોને અક્ષમ કરો છો તે આ બ્રાઉઝરના બધા વપરાશકર્તાઓ માટે સક્ષમ થશે. કૃપા કરીને સાવધાનીપૂર્વક આગળ વધો.</translation>
<translation id="3650584904733503804">માન્યતા સફળ</translation>
<translation id="370665806235115550">લોડ કરી રહ્યું છે...</translation>
<translation id="3712624925041724820">લાઇસેંસીસ પૂર્ણ</translation>
<translation id="3739623965217189342">તમે કૉપિ કરેલ લિંક</translation>
<translation id="375403751935624634">સર્વર ભૂલને કારણે ભાષાંતર નિષ્ફળ રહ્યું.</translation>
<translation id="385051799172605136">પાછળ</translation>
+<translation id="3858027520442213535">તારીખ અને સમય અપડેટ કરો</translation>
<translation id="3884278016824448484">વિરોધાભાસી ઉપકરણ ઓળખકર્તા</translation>
<translation id="3885155851504623709">પૅરિશ</translation>
<translation id="3934680773876859118">PDF દસ્તાવેજ લોડ કરવામાં નિષ્ફળ રહ્યા</translation>
<translation id="3963721102035795474">રીડર મોડ</translation>
<translation id="4030383055268325496">&amp;ઉમેરવું પૂર્વવત્ કરો</translation>
-<translation id="4058922952496707368">કી &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ચેતવણી</translation>
+<translation id="4058922952496707368">કી "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">પ્રોક્સી ગોઠવણી .pac સ્ક્રિપ્ટ URL નો ઉપયોગ કરવા માટે સેટ છે, નિયત પ્રોક્સી સર્વર્સ માટે નહીં.</translation>
<translation id="409504436206021213">ફરીથી લોડ કરવું નહીં</translation>
<translation id="4103249731201008433">ઉપકરણ અનુક્ર્માંક નંબર અમાન્ય છે</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">ખરાબ હસ્તાક્ષર</translation>
<translation id="4269787794583293679">(કોઇ વપરાશકર્તાનામ નથી)</translation>
<translation id="4300246636397505754">પેરેન્ટ સૂચનો</translation>
-<translation id="4372948949327679948">અપેક્ષિત <ph name="VALUE_TYPE"/> મૂલ્ય.</translation>
+<translation id="4325863107915753736">લેખ શોધવામાં નિષ્ફળ થયાં</translation>
+<translation id="4372948949327679948">અપેક્ષિત <ph name="VALUE_TYPE" /> મૂલ્ય.</translation>
+<translation id="4377125064752653719">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પ્રયાસ કર્યો, પણ સર્વર દ્વારા પ્રસ્તુત કરવામાં આવેલું પ્રમાણપત્ર તેના રજૂકર્તા દ્વારા જ રદ કરવામાં આવ્યું છે. આનો અર્થ છે કે સર્વરે પ્રસ્તુત કરેલા સુરક્ષા પ્રમાણપત્રો પૂર્ણપણે વિશ્વસનીય નથી. તમે કોઈ હુમલાખોર જોડે વાત કરતા હોઈ શકો છો.</translation>
+<translation id="4394049700291259645">અક્ષમ કરો</translation>
+<translation id="4424024547088906515">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર Chrome દ્વારા વિશ્વસનીય નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
<translation id="443673843213245140">પ્રોક્સીનો ઉપયોગ અક્ષમ કરેલો છે પણ એક સ્પષ્ટ પ્રોક્સી ગોઠવણી ઉલ્લેખિત છે.</translation>
-<translation id="4506176782989081258">માન્યતા ભૂલ: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">માન્યતા ભૂલ: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chrome માંથી સરનામું દૂર કરીએ?</translation>
<translation id="4594403342090139922">&amp;કાઢી નાખવું પૂર્વવત્‌ કરો</translation>
<translation id="4607653538520819196">આ પૃષ્ઠ ડેટા સેવર દ્વારા પ્રોક્સી કરી શકાતું નથી.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેના સુરક્ષા પ્રમાણપત્રમાં ભૂલો છે. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
<translation id="4726672564094551039">નીતિઓ ફરીથી લોડ કરો</translation>
+<translation id="4728558894243024398">પ્લેટફોર્મ</translation>
+<translation id="4771973620359291008">કોઈ અજ્ઞાત ભૂલ આવી.</translation>
<translation id="4800132727771399293">તમારી સમાપ્તિ તારીખ અને CVC તપાસો અને ફરીથી પ્રયાસ કરો</translation>
<translation id="4813512666221746211">નેટવર્ક ભૂલ</translation>
+<translation id="4816492930507672669">પૃષ્ઠ પર ફિટ</translation>
<translation id="4850886885716139402">જુઓ</translation>
-<translation id="4923417429809017348">આ પૃષ્ઠ કોઈ અજ્ઞાત ભાષામાંથી <ph name="LANGUAGE_LANGUAGE"/> માં અનુવાદિત કરવામાં આવ્યું છે</translation>
+<translation id="4923417429809017348">આ પૃષ્ઠ કોઈ અજ્ઞાત ભાષામાંથી <ph name="LANGUAGE_LANGUAGE" /> માં અનુવાદિત કરવામાં આવ્યું છે</translation>
<translation id="4926049483395192435">ઉલ્લેખિત હોવું આવશ્યક છે.</translation>
<translation id="4968547170521245791">પ્રોક્સી કરી શકાતું નથી</translation>
-<translation id="498957508165411911">શું <ph name="ORIGINAL_LANGUAGE"/> માંથી <ph name="TARGET_LANGUAGE"/> માં અનુવાદ કરીએ?</translation>
+<translation id="498957508165411911">શું <ph name="ORIGINAL_LANGUAGE" /> માંથી <ph name="TARGET_LANGUAGE" /> માં અનુવાદ કરીએ?</translation>
<translation id="5019198164206649151">બેકઅપ સ્ટોર કરવું ખરાબ સ્થિતિમાં છે</translation>
<translation id="5031870354684148875">Google અનુવાદ વિશે</translation>
+<translation id="5045550434625856497">ખોટો પાસવર્ડ</translation>
+<translation id="5087286274860437796">સર્વરનું પ્રમાણપત્ર આ સમયે માન્ય નથી.</translation>
<translation id="5089810972385038852">રાજ્ય</translation>
+<translation id="5094747076828555589">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર Chromium દ્વારા વિશ્વસનીય નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
<translation id="5095208057601539847">પ્રાંત</translation>
<translation id="5145883236150621069">નીતિ પ્રતિક્રિયામાં ભૂલ કોડ હાજર</translation>
<translation id="5172758083709347301">મશીન</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/> માં નથી? આ ભૂલની જાણ કરો </translation>
+<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> માં નથી? આ ભૂલની જાણ કરો </translation>
<translation id="5190835502935405962">બુકમાર્ક્સ બાર</translation>
+<translation id="5199729219167945352">પ્રયોગો</translation>
+<translation id="5251803541071282808">મેઘ</translation>
<translation id="5295309862264981122">નેવિગેશનની પુષ્ટિ કરો</translation>
<translation id="5299298092464848405">ભૂલ વિશ્લેષણ નીતિ</translation>
+<translation id="5316812925700871227">ઘડિયાળની વિપરિત દિશામાં ફેરવો</translation>
<translation id="5317780077021120954">સાચવો</translation>
<translation id="536296301121032821">નીતિ સેટિંગ્સ સ્ટોર કરવામાં નિષ્ફળ થયાં</translation>
-<translation id="5439770059721715174">&quot;<ph name="ERROR_PATH"/>&quot; પર સ્કીમા માન્યતા ભૂલ: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર આ સમયે માન્ય નથી. આ કોઇ ખોટી ગોઠવણીને કારણે થયું હોય અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો હોઇ શકે છે.</translation>
+<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" પર સ્કીમા માન્યતા ભૂલ: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">ખરાબ નીતિ સમયનોંધ</translation>
<translation id="5470861586879999274">&amp;સંપાદિત કરવું ફરી કરો</translation>
<translation id="5509780412636533143">સંચાલિત બુકમાર્ક્સ</translation>
<translation id="5523118979700054094">નીતિનું નામ</translation>
<translation id="552553974213252141">શું ટેક્સ્ટ ઠીકથી કાઢી હતી?</translation>
<translation id="5540224163453853">વિનંતી કરેલ લેખ શોધી શકાયો નથી.</translation>
+<translation id="5556459405103347317">ફરિથી લોડ કરો</translation>
<translation id="5565735124758917034">સક્રિય</translation>
<translation id="560412284261940334">સંચાલન સમર્થિત નથી</translation>
<translation id="5629630648637658800">નીતિ સેટિંગ્સ લોડ કરવામાં નિષ્ફળ થયાં</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">વર્તમાન વપરાશકર્તા</translation>
<translation id="5813119285467412249">&amp;ઉમેરવું ફરી કરો</translation>
<translation id="5872918882028971132">પેરેન્ટ સૂચનો</translation>
-<translation id="587701087903783706">મોબાઇલ-અનુકૂળ દૃશ્ય બંધ કરો</translation>
<translation id="59107663811261420">આ વેપારી માટે Google Payments દ્વારા આ પ્રકારના કાર્ડને સમર્થન નથી. કૃપા કરીને બીજું કાર્ડ પસંદ કરો.</translation>
+<translation id="5975083100439434680">ઝૂમ ઘટાડો</translation>
<translation id="5989320800837274978">નિયત પ્રોક્સી સર્વર્સ અથવા .pac સ્ક્રિપ્ટનો URL નો ઉલ્લેખ કરેલો નથી.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">બંધ કરો</translation>
+<translation id="6060685159320643512">સાવચેતી રાખો, આ પ્રયોગો નુકસાનકારક હોઈ શકે છે</translation>
+<translation id="6151417162996330722">સર્વર પ્રમાણપત્ર પાસે ખૂબ લાંબી હોય એવી માન્યતા અવધિ છે.</translation>
<translation id="6154808779448689242">પરત થયેલ નીતિ ટોકન વર્તમાન ટોકનથી મેળ ખાતો નથી</translation>
<translation id="6165508094623778733">વધુ જાણો</translation>
<translation id="6259156558325130047">&amp;પુનઃક્રમાંકિત કરવું ફરી કરો</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> બુકમાર્ક્સ</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> બુકમાર્ક્સ</translation>
<translation id="6282194474023008486">પોસ્ટલ કોડ</translation>
<translation id="6337534724793800597">નામ દ્વારા નીતિઓને ફિલ્ટર કરો</translation>
+<translation id="6387478394221739770">શું કૂલ નવી Chrome સુવિધાઓમાં રુચિ ધરાવો છો? chrome.com/beta પર અમારી બીટા ચેનલ અજમાવી જુઓ.</translation>
+<translation id="6426993025560594914">તમારા પ્લેટફોર્મ પર બધા પ્રયોગો ઉપલબ્ધ છે!</translation>
<translation id="6445051938772793705">દેશ</translation>
<translation id="6458467102616083041">અવગણો કારણ કે નીતિ દ્વારા ડિફૉલ્ટ શોધ અક્ષમ કરેલી છે.</translation>
<translation id="647261751007945333">ઉપકરણ નીતિઓ</translation>
<translation id="6512448926095770873">આ પૃષ્ઠ છોડો</translation>
<translation id="6529602333819889595">&amp;કાઢી નાખવું ફરી કરો</translation>
<translation id="6550675742724504774">વિકલ્પો</translation>
-<translation id="6597614308054261376">તમે <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> પર પહોંચવાનો પ્રયાસ કરી રહ્યાં છો. ડેટા સેવર દ્વારા આ સમયે આ પૃષ્ઠ પ્રોક્સી કરી શકાતું નથી.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> શોધ</translation>
+<translation id="6597614308054261376">તમે <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પર પહોંચવાનો પ્રયાસ કરી રહ્યાં છો. ડેટા સેવર દ્વારા આ સમયે આ પૃષ્ઠ પ્રોક્સી કરી શકાતું નથી.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> શોધ</translation>
<translation id="6644283850729428850">આ નીતિ દૂર કરવામાં આવેલી છે.</translation>
<translation id="6646897916597483132">તમારા કાર્ડની આગળની બાજુ પરથી 4-અંકનો CVC દાખલ કરો</translation>
+<translation id="674375294223700098">અજ્ઞાત સર્વર પ્રમાણપત્ર ભૂલ.</translation>
<translation id="6753269504797312559">નીતિ મૂલ્ય</translation>
<translation id="6831043979455480757">અનુવાદ કરો</translation>
<translation id="6839929833149231406">વિસ્તાર</translation>
<translation id="6874604403660855544">&amp;ઉમેરવું ફરી કરો</translation>
<translation id="6891596781022320156">નીતિ સ્તર સમર્થિત નથી.</translation>
<translation id="6915804003454593391">વપરાશકર્તા: </translation>
+<translation id="6957887021205513506">સર્વરનું પ્રમાણપત્ર બનાવટી હોય એવું લાગે છે.</translation>
<translation id="6965382102122355670">ઓકે</translation>
<translation id="6965978654500191972">ઉપકરણ</translation>
<translation id="6970216967273061347">જીલ્લો</translation>
<translation id="6973656660372572881">નિયત પ્રોક્સી સર્વર્સ અને .pac script URL બન્નેનો ઉલ્લેખ કરેલો છે.</translation>
<translation id="6980028882292583085">Javascript ચેતવણી</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પ્રયાસ કરેલો, પરંતુ સર્વરે એવું પ્રમાણપત્ર પ્રસ્તુત કર્યું જેની માન્યતા અવધિ, વિશ્વસનીય હોવા માટે ખૂબ લાંબી છે.</translation>
<translation id="7087282848513945231">પરગણું</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/> માં અનુવાદ નિષ્ફળ રહ્યો.</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" /> માં અનુવાદ નિષ્ફળ રહ્યો.</translation>
<translation id="7139724024395191329">એમિરાત</translation>
+<translation id="7179921470347911571">હમણાં ફરીથી લોંચ કરો</translation>
<translation id="7180611975245234373">તાજું કરો</translation>
<translation id="7182878459783632708">કોઈ નીતિઓ સેટ નથી</translation>
-<translation id="7186367841673660872">આ પૃષ્ઠનું<ph name="ORIGINAL_LANGUAGE"/>માંથી<ph name="LANGUAGE_LANGUAGE"/>માં ભાષાંતર કરવામાં આવ્યું છે.</translation>
+<translation id="7186367841673660872">આ પૃષ્ઠનું<ph name="ORIGINAL_LANGUAGE" />માંથી<ph name="LANGUAGE_LANGUAGE" />માં ભાષાંતર કરવામાં આવ્યું છે.</translation>
<translation id="719464814642662924">વિઝા</translation>
-<translation id="7208899522964477531"><ph name="SEARCH_TERMS"/> માટે <ph name="SITE_NAME"/> શોધો</translation>
+<translation id="7208899522964477531"><ph name="SEARCH_TERMS" /> માટે <ph name="SITE_NAME" /> શોધો</translation>
+<translation id="725866823122871198"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> પર ખાનગી કનેક્શન સ્થાપિત કરી શકાતું નથી કારણ કે તમારા ઉપકરણની તારીખ અને સમય (<ph name="DATE_AND_TIME" />) અયોગ્ય છે.</translation>
<translation id="7275334191706090484">સંચાલિત બુકમાર્ક્સ</translation>
<translation id="7298195798382681320">ભલામણ કરેલ</translation>
<translation id="7334320624316649418">&amp;પુનઃક્રમાંકિત કરવું ફરી કરો</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">ફરજિયાત</translation>
<translation id="7542995811387359312">આપમેળે ક્રેડિટ કાર્ડ ભરણ અક્ષમ કર્યું છે કારણ કે આ ફોર્મ સુરક્ષિત કનેક્શનનો ઉપયોગ કરતું નથી.</translation>
-<translation id="7568593326407688803">આ પૃષ્ઠ<ph name="ORIGINAL_LANGUAGE"/>માં છે શું તમે તેને અનુવાદિત કરવા માંગો છો?</translation>
+<translation id="7567204685887185387">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર કપટપૂર્વક રજૂ કરવામાં આવેલ હોઈ શકે છે. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
+<translation id="7568593326407688803">આ પૃષ્ઠ<ph name="ORIGINAL_LANGUAGE" />માં છે શું તમે તેને અનુવાદિત કરવા માંગો છો?</translation>
<translation id="7569952961197462199">Chrome માંથી ક્રેડિટ કાર્ડ દૂર કરીએ?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/> નું ક્યારેય અનુવાદ કરશો નહીં</translation>
-<translation id="7610193165460212391">મૂલ્ય <ph name="VALUE"/> શ્રેણી બહારનું છે.</translation>
+<translation id="7592362899630581445">સર્વરનું પ્રમાણપત્ર, નામ નિગ્રહોનું ઉલ્લંઘન કરે છે.</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" /> નું ક્યારેય અનુવાદ કરશો નહીં</translation>
+<translation id="7610193165460212391">મૂલ્ય <ph name="VALUE" /> શ્રેણી બહારનું છે.</translation>
+<translation id="7674629440242451245">શું કૂલ નવી Chrome સુવિધાઓમાં રુચિ ધરાવો છો? chrome.com/dev પર અમારી dev ચૅનલ અજમાવી જુઓ.</translation>
<translation id="7752995774971033316">બિનસંચાલિત</translation>
+<translation id="7761701407923456692">સર્વરનું પ્રમાણપત્ર URL સાથે મેળ ખાતું નથી.</translation>
<translation id="777702478322588152">પ્રીફેચર</translation>
<translation id="7791543448312431591">ઉમેરો</translation>
<translation id="7805768142964895445">સ્થિતિ</translation>
<translation id="7813600968533626083">Chrome માંથી ફોર્મ સૂચનો દૂર કરીએ?</translation>
<translation id="7887683347370398519">તમારું CVC તપાસો અને ફરીથી પ્રયાસ કરો</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">સર્વરનું પ્રમાણપત્ર હજી માન્ય નથી.</translation>
<translation id="7956713633345437162">મોબાઇલ બુકમાર્ક્સ</translation>
<translation id="7961015016161918242">ક્યારેય નહીં</translation>
<translation id="7977590112176369853">&lt;ક્વેરી દાખલ કરો&gt;</translation>
-<translation id="7983301409776629893">હંમેશા <ph name="ORIGINAL_LANGUAGE"/> નું <ph name="TARGET_LANGUAGE"/> માં ભાષાંતર કરો</translation>
+<translation id="7983301409776629893">હંમેશા <ph name="ORIGINAL_LANGUAGE" /> નું <ph name="TARGET_LANGUAGE" /> માં ભાષાંતર કરો</translation>
<translation id="7988324688042446538">ડેસ્કટૉપ બુકમાર્ક્સ</translation>
<translation id="7995512525968007366">નિર્દિષ્ટ કરાયેલ નથી</translation>
-<translation id="8034522405403831421">આ પૃષ્ઠ <ph name="SOURCE_LANGUAGE"/> માં છે. શું તેનો અનુવાદ <ph name="TARGET_LANGUAGE"/> માં કરીએ?</translation>
+<translation id="8003882219468422867">એન્ટરપ્રાઇઝ ઓવરરાઈડ</translation>
+<translation id="8034522405403831421">આ પૃષ્ઠ <ph name="SOURCE_LANGUAGE" /> માં છે. શું તેનો અનુવાદ <ph name="TARGET_LANGUAGE" /> માં કરીએ?</translation>
<translation id="8088680233425245692">લેખ જોવામાં નિષ્ફળ થયાં.</translation>
<translation id="8091372947890762290">સક્રિયતા સર્વર પર બાકી છે</translation>
<translation id="8194797478851900357">&amp;ખસેડવું પૂર્વવત્‌ કરો</translation>
-<translation id="8201077131113104583">ID &quot;<ph name="EXTENSION_ID"/>&quot; સાથેના એક્સટેન્શન માટે અમાન્ય અપડેટ URL.</translation>
+<translation id="8201077131113104583">ID "<ph name="EXTENSION_ID" />" સાથેના એક્સટેન્શન માટે અમાન્ય અપડેટ URL.</translation>
<translation id="8208216423136871611">સાચવશો નહીં</translation>
<translation id="8218327578424803826">સોંપાયેલ સ્થાન:</translation>
<translation id="8249320324621329438">છેલ્લું આનયન:</translation>
+<translation id="8294431847097064396">સ્રોત</translation>
<translation id="8308427013383895095">નેટવર્ક કનેક્શનમાં સમસ્યાને કારણે ભાષાંતર નિષ્ફળ રહ્યું.</translation>
<translation id="8311778656528046050">શું તમે ખરેખર આ પૃષ્ઠને ફરીથી લોડ કરવા માંગો છો?</translation>
<translation id="8349305172487531364">બુકમાર્ક્સ બાર</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">આમને લાગુ</translation>
<translation id="8530504477309582336">Google Payments દ્વારા આ પ્રકારના કાર્ડને સમર્થન નથી. કૃપા કરીને બીજું કાર્ડ પસંદ કરો.</translation>
<translation id="8553075262323480129">ભાષાંતર નિષ્ફળ રહ્યું કારણ કે પૃષ્ઠની ભાષા નિર્ધારિત થઈ શકી નથી.</translation>
-<translation id="8571890674111243710">પૃષ્ઠને <ph name="LANGUAGE"/> માં અનુવાદિત કરી રહ્યું છે...</translation>
+<translation id="8559762987265718583"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> પર ખાનગી કનેક્શન સ્થાપિત કરી શકાતું નથી કારણ કે તમારા ઉપકરણની તારીખ અને સમય (<ph name="DATE_AND_TIME" />) અયોગ્ય છે.</translation>
+<translation id="8571890674111243710">પૃષ્ઠને <ph name="LANGUAGE" /> માં અનુવાદિત કરી રહ્યું છે...</translation>
+<translation id="8647750283161643317">બધાને ડિફોલ્ટ પર ફરીથી સેટ કરો</translation>
<translation id="8713130696108419660">ખોટી ટૂંકી સહી</translation>
<translation id="8725066075913043281">ફરી પ્રયાસ કરો</translation>
+<translation id="8738058698779197622">એક સુરક્ષિત કનેક્શન સ્થાપિત કરવા માટે, તમારું ઘડિયાળ યોગ્ય રીતે સેટ હોવું જરૂરી છે. આનું કારણ એ કે વેબસાઇટ્સ તેઓને ઓળખવા માટે જે પ્રમાણપત્રોનો ઉપયોગ કરે છે તે ચોક્કસ સમય અવધિ માટે જ માન્ય હોય છે. તમારા ઉપકરણની ઘડિયાળ ખોટી હોવાને લીધે, Chromium આ પ્રમાણપત્રોને ચકાસી શકતું નથી.</translation>
<translation id="8790007591277257123">&amp;કાઢી નાખવું ફરી કરો</translation>
<translation id="8804164990146287819">ગોપનીયતા નીતિ</translation>
+<translation id="8820817407110198400">બુકમાર્ક્સ</translation>
<translation id="8824019021993735287">આ સમયે Chrome તમારું કાર્ડ ચકાસવા અસમર્થ હતું. કૃપા કરીને પછી ફરીથી પ્રયત્ન કરશો.</translation>
<translation id="8834246243508017242">સંપર્કોનો ઉપયોગ કરીને સ્વતઃભરણ સક્ષમ કરો...</translation>
<translation id="883848425547221593">અન્ય બુકમાર્ક્સ</translation>
+<translation id="884923133447025588">રદ કરવાની કોઈ મેકેનિઝમ મળી નથી.</translation>
<translation id="8866481888320382733">ભૂલ વિશ્લેષણ નીતિ સેટિંગ્સ</translation>
<translation id="8876793034577346603">નેટવર્ક ગોઠવણી વિશ્લેષિત થવામાં નિષ્ફળ થઇ.</translation>
<translation id="8891727572606052622">અમાન્ય પ્રોક્સી મોડ.</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/> આદેશ ચલાવો: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">માફ કરશો, આ પ્રયોગ તમારા પ્લેટફોર્મ પર ઉપલબ્ધ નથી.</translation>
+<translation id="8903921497873541725">ઝૂમ વધારો</translation>
+<translation id="8932102934695377596">તમારી ઘડિયાળ પાછળ છે</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" /> આદેશ ચલાવો: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">સર્વરના પ્રમાણપત્રની સમયસીમા સમાપ્ત થઈ છે.</translation>
<translation id="8988760548304185580">તમારા કાર્ડની પાછળની બાજુ પરથી સમાપ્તિ તારીખ અને 3-અંકનો CVC દાખલ કરો</translation>
-<translation id="9020542370529661692">આ પૃષ્ઠનો <ph name="TARGET_LANGUAGE"/> માં અનુવાદ કરવામાં આવ્યો છે</translation>
+<translation id="901974403500617787">ધ્વજો કે જે સિસ્ટમ-વ્યાપી લાગુ છે તે ફક્ત માલિક દ્વારા જ સેટ કરી શકાય છે: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">આ પૃષ્ઠનો <ph name="TARGET_LANGUAGE" /> માં અનુવાદ કરવામાં આવ્યો છે</translation>
+<translation id="9049981332609050619">તમે <ph name="DOMAIN" /> સુધી પહોંચવાનો પ્રયાસ કર્યો, પરંતુ સર્વરે અમાન્ય પ્રમાણપત્ર પ્રસ્તુત કર્યું. </translation>
<translation id="9125941078353557812">તમારા કાર્ડની પાછળની બાજુ પરથી 3-અંકનો CVC દાખલ કરો</translation>
<translation id="9137013805542155359">મૂળ બતાવો</translation>
<translation id="9148507642005240123">&amp;સંપાદિત કરવું પૂર્વવત્‌ કરો</translation>
<translation id="9154176715500758432">આ પૃષ્ઠ પર રહો</translation>
<translation id="9170848237812810038">&amp;પૂર્વવત્ કરો</translation>
+<translation id="917450738466192189">સર્વરનું પ્રમાણપત્ર અમાન્ય છે.</translation>
+<translation id="9187827965378254003">ઓહ, લાગે છે કે ત્યાં હાલમાં કોઈ પ્રયોગો ઉપલબ્ધ નથી.</translation>
<translation id="9207861905230894330">લેખ ઉમેરવામાં નિષ્ફળ થયાં.</translation>
<translation id="933712198907837967">ડાઇનર્સ ક્લબ</translation>
+<translation id="935608979562296692">ફોર્મ સાફ કરો</translation>
+<translation id="988159990683914416">વિકાસકર્તા બિલ્ડ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_hi.xtb b/chromium/components/strings/components_strings_hi.xtb
index b5d99c76496..9c354701da0 100644
--- a/chromium/components/strings/components_strings_hi.xtb
+++ b/chromium/components/strings/components_strings_hi.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="hi">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hi">
+<translation id="1032854598605920125">घड़ी की दिशा में घुमाएं</translation>
<translation id="1055184225775184556">&amp;जोड़ना वापस लाएं</translation>
<translation id="106701514854093668">डेस्कटॉप बुकमार्क</translation>
-<translation id="1103523840287552314"><ph name="LANGUAGE"/> का हमेशा अनुवाद करें</translation>
+<translation id="1080116354587839789">चौड़ाई में फ़िट करें</translation>
+<translation id="1103523840287552314"><ph name="LANGUAGE" /> का हमेशा अनुवाद करें</translation>
<translation id="1113869188872983271">&amp;पुन: क्रमित करना वापस लाएं</translation>
<translation id="111844081046043029">क्या आप वाकई इस पृष्ठ को छोड़ना चाहते हैं ?</translation>
<translation id="112840717907525620">नीति संचय ठीक है</translation>
<translation id="1132774398110320017">Chrome स्‍वत:-भरण सेटिंग...</translation>
-<translation id="1152921474424827756"><ph name="URL"/> की <ph name="BEGIN_LINK"/>संचित प्रति<ph name="END_LINK"/> एक्सेस करें</translation>
+<translation id="1150979032973867961">यह सर्वर यह नहीं प्रमाणित कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र आपके कंप्यूटर के ऑपरेटिंग सिस्टम द्वारा विश्वसनीय नहीं है. ऐसा गलत कॉन्फ़िगरेशन या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
+<translation id="1152921474424827756"><ph name="URL" /> की <ph name="BEGIN_LINK" />संचित प्रति<ph name="END_LINK" /> एक्सेस करें</translation>
+<translation id="121201262018556460">आपने <ph name="DOMAIN" /> तक पहुंचने का प्रयास किया, लेकिन लेकिन सर्वर ने कमज़ोर कुंजी वाला प्रमाणपत्र प्रस्‍तुत किया. संभवत: हमलावर ने निजी कुंजी का पता लगा लिया है, और हो सकता है कि सर्वर आपका अपेक्षित सर्वर न हो (हो सकता है कि आप किसी हमलावर से बातचीत कर रहे हों).</translation>
<translation id="1227224963052638717">अज्ञात नीति.</translation>
<translation id="1227633850867390598">मान छिपाएं</translation>
<translation id="1228893227497259893">गलत इकाई पहचानकर्ता</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">नामांकन डोमेन:</translation>
<translation id="1344588688991793829">क्रोमियम स्वत: भरण सेटिंग...</translation>
<translation id="1426410128494586442">हां</translation>
+<translation id="1430915738399379752">प्रिंट करें</translation>
<translation id="1455235771979731432">आपका कार्ड सत्‍यापित करते समय समस्‍या हुई थी. अपना इंटरनेट कनेक्‍शन जांचें और पुन: प्रयास करें.</translation>
<translation id="1491151370853475546">यह पृष्ठ पुन: लोड करें</translation>
<translation id="1549470594296187301">इस सुविधा का उपयोग करने के लिए JavaScript को सक्षम किया जाना चाहिए.</translation>
-<translation id="1639239467298939599">लोड हो रहा है</translation>
<translation id="1640180200866533862">उपयोगकर्ता नीतियां</translation>
<translation id="1644184664548287040">नेटवर्क कॉन्फ़िगरेशन अमान्य है और उसे आयात नहीं किया जा सकेगा.</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> पर मौजूद पृष्ठ कहता है:</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="168841957122794586">सर्वर प्रमाणपत्र में कमज़ोर क्रिप्टोग्राफ़िक कुंजी है.</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> पर मौजूद पृष्ठ कहता है:</translation>
+<translation id="1706954506755087368">{1,plural, =1{यह सर्वर प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र कल से माना जाएगा. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन को बाधित करने के कारण हो सकता है.}one{यह सर्वर प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र # दिन बाद से माना जाएगा. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन को बाधित करने के कारण हो सकता है.}other{यह सर्वर प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र # दिन बाद से माना जाएगा. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन को बाधित करने के कारण हो सकता है.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">यह सर्वर यह नहीं प्रमाणित कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र आपके डिवाइस के ऑपरेटिंग सिस्टम द्वारा विश्वसनीय नहीं है. ऐसा गलत कॉन्फ़िगरेशन या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="1821930232296380041">अमान्य अनुरोध या अनुरोध पैरामीटर</translation>
-<translation id="1853748787962613237">लेख प्रदर्शित करने में विफल रहा.</translation>
<translation id="1871208020102129563">प्रॉक्‍सी को फ़िक्‍स्‍ड प्रॉक्‍सी सर्वर का उपयोग करने के लिए सेट किया गया है, .pac स्‍क्रिप्‍ट फ़ाइल का उपयोग करने के लिए नहीं.</translation>
-<translation id="1875753206475436906">अनुमानी प्रकार: <ph name="HEURISTIC_TYPE"/>
- सर्वर प्रकार: <ph name="SERVER_TYPE"/>
- फ़ील्ड हस्ताक्षर: <ph name="FIELD_SIGNATURE"/>
- फ़ॉर्म हस्ताक्षर: <ph name="FORM_SIGNATURE"/>
- प्रयोग आईडी: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158"><ph name="LINK"/> पर जाएं</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> बुकमार्क</translation>
+<translation id="194030505837763158"><ph name="LINK" /> पर जाएं</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> बुकमार्क</translation>
<translation id="1973335181906896915">क्रमबद्ध करने में त्रुटि</translation>
+<translation id="1974060860693918893">उन्नत</translation>
<translation id="2025186561304664664">प्रॉक्‍सी स्‍वत: कॉन्‍फ़‍िगर पर सेट है.</translation>
<translation id="2025623846716345241">फिर से लोड की दुबारा पूछें</translation>
-<translation id="2030481566774242610">क्या आप मतलब <ph name="LINK"/> से है?</translation>
+<translation id="2030481566774242610">क्या आप मतलब <ph name="LINK" /> से है?</translation>
<translation id="2053553514270667976">ज़िप कोड</translation>
<translation id="20817612488360358">सिस्‍टम प्रॉक्‍सी सेटिंग उपयोग किए जाने के लिए सेट हैं लेकिन कोई स्पष्‍ट प्रॉक्‍सी कॉन्फ़िगरेशन भी निर्दिष्ट है.</translation>
<translation id="2094505752054353250">डोमेन का गलत-मिलान</translation>
<translation id="2096368010154057602">विभाग</translation>
<translation id="2113977810652731515">कार्ड</translation>
-<translation id="2114841414352855701">ध्यान नहीं दिया गया क्योंकि यह <ph name="POLICY_NAME"/> द्वारा ओवरराइड की गई थी.</translation>
+<translation id="2114841414352855701">ध्यान नहीं दिया गया क्योंकि यह <ph name="POLICY_NAME" /> द्वारा ओवरराइड की गई थी.</translation>
+<translation id="2128531968068887769">स्थानीय क्लाइंट</translation>
<translation id="213826338245044447">मोबाइल बुकमार्क</translation>
+<translation id="2171101176734966184">आपने <ph name="DOMAIN" /> तक पहुंचने का प्रयास किया, लेकिन सर्वर ने कमज़ोर हस्ताक्षर एल्‍गोरिदम का उपयोग करते हुए हस्ताक्षरित प्रमाणपत्र प्रस्तुत किया. इसका अर्थ यह है कि सर्वर द्वारा प्रस्तुत किए गए सुरक्षा प्रमाणिकता नकली हो सकते हैं, और हो सकता है कि सर्वर आपका अपेक्षित सर्वर न हो (हो सकता है कि आप किसी हमलावर से बातचीत कर रहे हों).</translation>
<translation id="2181821976797666341">नीतियां</translation>
<translation id="2212735316055980242">नीति नहीं मिली</translation>
<translation id="2213606439339815911">प्रविष्टियां फ़ेच की जा रही हैं...</translation>
<translation id="225207911366869382">यह मान इस नीति के लिए हटा दिया गया है.</translation>
<translation id="2262243747453050782">HTTP त्रुटि</translation>
-<translation id="2270192940992995399">लेख ढूंढने में विफल रहा.</translation>
-<translation id="2328300916057834155"><ph name="ENTRY_INDEX"/> अनुक्रमणिका पर अमान्य बुकमार्क को अनदेखा किया गया</translation>
+<translation id="2282872951544483773">अनुपलब्ध प्रयोग</translation>
+<translation id="229702904922032456">किसी रूट या मध्यवर्ती प्रमाणपत्र की अवधि समाप्त हो गई है.</translation>
+<translation id="2328300916057834155"><ph name="ENTRY_INDEX" /> अनुक्रमणिका पर अमान्य बुकमार्क को अनदेखा किया गया</translation>
<translation id="2354001756790975382">अन्य बुकमार्क</translation>
<translation id="2359808026110333948">जारी रखें</translation>
<translation id="2367567093518048410">स्तर</translation>
+<translation id="2384307209577226199">एंटरप्राइज़ डिफ़ॉल्ट</translation>
+<translation id="2386255080630008482">सर्वर का प्रमाणपत्र निरस्त कर दिया गया है.</translation>
<translation id="2392959068659972793">कोई भी मान सेट नहीं की गई नीतियां दिखाएं</translation>
<translation id="2396249848217231973">&amp;हटाना वापस लाएं</translation>
+<translation id="2413528052993050574">यह सर्वर यह प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" />; इसका सुरक्षा प्रमाणपत्र निरस्त कर दिया गया है. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="2455981314101692989">इस वेब पृष्‍ठ पर इस फ़ॉर्म को स्‍वत: भरना अक्षम किया गया है.</translation>
<translation id="2479410451996844060">अमान्‍य खोज URL.</translation>
+<translation id="2491120439723279231">सर्वर के प्रमाणपत्र में त्रुटियां हैं.</translation>
<translation id="2495083838625180221">JSON पार्सर</translation>
<translation id="2498091847651709837">नया कार्ड स्‍कैन करें</translation>
<translation id="2556876185419854533">&amp;संपादन वापस लाएं</translation>
-<translation id="2581221116934462656">क्‍या आप चाहते हैं कि <ph name="PRODUCT_NAME"/> अगली बार इस साइट के <ph name="LANGUAGE_NAME"/> पृष्‍ठों का अनुवाद करे?</translation>
+<translation id="2581221116934462656">क्‍या आप चाहते हैं कि <ph name="PRODUCT_NAME" /> अगली बार इस साइट के <ph name="LANGUAGE_NAME" /> पृष्‍ठों का अनुवाद करे?</translation>
<translation id="2587841377698384444">निर्देशिका API आईडी:</translation>
<translation id="2597378329261239068">यह दस्तावेज़ पासवर्ड सुरक्षित है. कृपया पासवर्ड डालें.</translation>
+<translation id="2625385379895617796">आपकी घड़ी आगे है</translation>
<translation id="2639739919103226564">स्थिति:</translation>
+<translation id="2653659639078652383">सबमिट करें</translation>
<translation id="2704283930420550640">मान का प्रारूप से मिलान नहीं होता.</translation>
<translation id="2721148159707890343">अनुरोध सफल रहा</translation>
+<translation id="2728127805433021124">सर्वर का प्रमाणपत्र एक कमज़ोर हस्ताक्षर एल्गोरिदम का उपयोग करके हस्ताक्षरित किया गया है.</translation>
<translation id="2774256287122201187">आप जारी रख सकते हैं. यदि आप पृष्‍ठ में जारी रखते हैं, तो यह चेतावनी पांच मिनट तक फिर से दिखाई नहीं देगी.</translation>
<translation id="277499241957683684">डिवाइस का रिकॉर्ड लापता है</translation>
<translation id="2835170189407361413">फ़ॉर्म साफ़ करें</translation>
-<translation id="2855922900409897335">अपना <ph name="CREDIT_CARD"/> सत्‍यापित करें</translation>
+<translation id="2855922900409897335">अपना <ph name="CREDIT_CARD" /> सत्‍यापित करें</translation>
+<translation id="2915500479781995473">यह सर्वर प्रमाणित नहीं कर सका कि वह <ph name="DOMAIN" /> है; उसका सुरक्षा प्रमाणपत्र समाप्त हो गया था. ऐसा गलत कॉन्फ़िगरेशन या किसी आक्रमणकर्ता द्वारा आपका कनेक्शन अवरोधित करने के कारण हो सकता है. अभी आपके कंप्यूटर की घड़ी <ph name="CURRENT_TIME" /> पर सेट है. क्या यह सही लग रहा है? यदि नहीं, तो आपको अपने सिस्टम की घड़ी सही करनी चाहिए और फिर इस पृष्ठ को रीफ्रेश करना चाहिए.</translation>
+<translation id="2922350208395188000">सर्वर प्रमाणपत्र की जांच नहीं की जा सकती.</translation>
+<translation id="2941952326391522266">यह सर्वर यह प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र <ph name="DOMAIN2" /> की ओर से है. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="2958431318199492670">नेटवर्क कॉन्फ़िगरेशन ONC मानक का पालन नहीं करता. कॉन्फ़िगरेशन के कुछ भाग आयात नहीं किए जा सकते हैं.</translation>
<translation id="2972581237482394796">&amp;फिर से करें</translation>
-<translation id="3010559122411665027">सूची प्रविष्ट‍ि &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">सूची प्रविष्ट‍ि "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">गलत नीति प्रकार</translation>
<translation id="3105172416063519923">एसेट आईडी:</translation>
<translation id="3145945101586104090">उत्तर डीकोड करने में विफल</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">तलाश करें</translation>
<translation id="3174168572213147020">द्वीप</translation>
<translation id="3219579145727097045">अवधि समाप्‍ति दिनांक और अपने कार्ड के सामने की ओर दिया गया 4 अंकों वाला CVC डालें</translation>
-<translation id="3228969707346345236">अनुवाद विफल हो गया क्योंकि पृष्ठ पहले से ही <ph name="LANGUAGE"/> में है.</translation>
+<translation id="3225919329040284222">सर्वर द्वारा कोई प्रमाणपत्र प्रस्‍तुत किया गया, जो बिल्‍ट-इन अपेक्षाओं से मिलान नहीं करता. इन अपेक्षाओं को आपकी सुरक्षा करने के लिए कुछ, उच्‍च-सुरक्षा वेबसाइटों के लिए शामिल किया गया है.</translation>
+<translation id="3228969707346345236">अनुवाद विफल हो गया क्योंकि पृष्ठ पहले से ही <ph name="LANGUAGE" /> में है.</translation>
<translation id="3270847123878663523">&amp;पुन: क्रमित करना वापस लाएं</translation>
+<translation id="3286538390144397061">अभी फिर से प्रारंभ करें</translation>
<translation id="333371639341676808">इस पृष्ठ को अतिरिक्त ब्लॉग बनाने से रोकें.</translation>
-<translation id="3369366829301677151">अपना <ph name="CREDIT_CARD"/> अपडेट करें और सत्‍यापित करें</translation>
+<translation id="3340978935015468852">सेटिंग</translation>
+<translation id="3369192424181595722">घड़ी त्रुटि</translation>
+<translation id="3369366829301677151">अपना <ph name="CREDIT_CARD" /> अपडेट करें और सत्‍यापित करें</translation>
<translation id="337363190475750230">प्रावधान रद्द</translation>
<translation id="3377188786107721145">नीति पार्स त्रुटि</translation>
<translation id="3380365263193509176">अज्ञात त्रुटि</translation>
<translation id="3380864720620200369">क्लाइंट आईडी:</translation>
<translation id="3427342743765426898">&amp;संपादित करना फिर से करें</translation>
+<translation id="3435896845095436175">सक्षम करें</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">प्राप्ति अंतराल:</translation>
+<translation id="3462200631372590220">उन्नत को छिपाएं</translation>
+<translation id="3528171143076753409">सर्वर का प्रमाणपत्र विश्वसनीय नहीं है.</translation>
<translation id="3542684924769048008">इसके लिए पासवर्ड का उपयोग करें:</translation>
<translation id="3583757800736429874">&amp;ले जाना फिर से करें</translation>
<translation id="3623476034248543066">मान दिखाएं</translation>
+<translation id="3648607100222897006">ये प्रायोगिक विशेषताएं किसी भी समय बदल, अनिरंतर या गायब हो सकती हैं. हम इस बात की कोई भी गारंटी नहीं दे सकते कि आपके द्वारा इनमें से किसी भी प्रयोग को चालू करने पर क्या हो सकता है, और यहां तक कि आपका ब्राउज़र नष्ट भी हो सकता है. मज़ाक छोड़ें, आपका ब्राउज़र आपका पूरा डेटा हटा सकता है, या आपकी सुरक्षा और गोपनीयता अप्रत्याशित रूप से ख़तरे में पड़ सकती है. आपके द्वारा सक्षम किए गए कोई भी प्रयोग इस ब्राउज़र के सभी उपयोगकर्ताओं के लिए सक्षम होंगे. कृपया सावधानी से आगे बढ़ें.</translation>
<translation id="3650584904733503804">मान्यकरण सफल</translation>
<translation id="370665806235115550">लोड हो रहा है...</translation>
<translation id="3712624925041724820">लाइसेंस समाप्त हो गए</translation>
<translation id="3739623965217189342">काॅपी किया गया लिंक</translation>
<translation id="375403751935624634">सर्वर त्रुटि के कारण अनुवाद विफल.</translation>
<translation id="385051799172605136">वापस</translation>
+<translation id="3858027520442213535">दिनांक और समय अपडेट करें</translation>
<translation id="3884278016824448484">विरोधाभासी डिवाइस पहचानकर्ता</translation>
<translation id="3885155851504623709">पैरिश</translation>
<translation id="3934680773876859118">PDF दस्तावेज़ लोड करने में विफल</translation>
<translation id="3963721102035795474">रीडर मोड</translation>
<translation id="4030383055268325496">&amp;जोड़ना वापस लाएं</translation>
-<translation id="4058922952496707368">कुंजी &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">चेतावनी</translation>
+<translation id="4058922952496707368">कुंजी "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">प्रॉक्‍सी कॉन्‍फ़िगरेशन को .pac स्‍क्रिप्‍ट URL का उपयोग करने के लिए सेट किया जाता है, फ़िक्‍स्‍ड प्रॉक्‍सी सर्वर के लिए नहीं.</translation>
<translation id="409504436206021213">फिर से लोड न करें</translation>
<translation id="4103249731201008433">डिवाइस की क्रम संख्या अमान्य है</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">खराब हस्ताक्षर</translation>
<translation id="4269787794583293679">(कोई उपयोगकर्ता नाम नहीं)</translation>
<translation id="4300246636397505754">अभिभावक सुझाव</translation>
-<translation id="4372948949327679948">अपेक्षित <ph name="VALUE_TYPE"/> मान.</translation>
+<translation id="4325863107915753736">लेख ढूंढ़ने में विफल</translation>
+<translation id="4372948949327679948">अपेक्षित <ph name="VALUE_TYPE" /> मान.</translation>
+<translation id="4377125064752653719">आपने <ph name="DOMAIN" /> तक पहुंचने का प्रयास किया, लेकिन सर्वर द्वारा प्रस्तुत प्रमाणपत्र को उसके जारीकर्ता द्वारा रद्द कर दिया गया है. इसका अर्थ है कि सर्वर द्वारा प्रस्तुत सुरक्षा प्रमाणिकता पर पूर्णतया विश्वास नहीं करना चाहिए. हो सकता है कि आप किसी हमलावर से बातचीत कर रहे हों.</translation>
+<translation id="4394049700291259645">अक्षम करें</translation>
+<translation id="4424024547088906515">यह सर्वर यह नहीं प्रमाणित कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र Chrome द्वारा विश्वसनीय नहीं है. ऐसा गलत कॉन्फ़िगरेशन या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="443673843213245140">प्रॉक्‍सी का उपयोग अक्षम है लेकिन कोई स्‍पष्ट प्रॉक्‍सी कॉन्फ़िगरेशन निर्दिष्ट किया गया है.</translation>
-<translation id="4506176782989081258">सत्‍यापन त्रुटि: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">सत्‍यापन त्रुटि: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chrome से पता निकालें?</translation>
<translation id="4594403342090139922">&amp;हटाना वापस लाएं</translation>
<translation id="4607653538520819196">इस पृष्‍ठ को डेटा बचतकर्ता द्वारा प्रॉक्‍सी नहीं किया जा सकता.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">यह सर्वर यह प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सुरक्षा प्रमाणपत्र में त्रुटियां हैं. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="4726672564094551039">नीतियां फिर से लोड करें</translation>
+<translation id="4728558894243024398">प्लेटफ़ॉर्म</translation>
+<translation id="4771973620359291008">अज्ञात त्रुटि आई.</translation>
<translation id="4800132727771399293">अपना अवधि समाप्‍ति दिनांक और CVC जांचें और पुन: प्रयास करें</translation>
<translation id="4813512666221746211">नेटवर्क त्रुटि</translation>
+<translation id="4816492930507672669">पृष्ठ में फ़िट करें</translation>
<translation id="4850886885716139402">देखें</translation>
-<translation id="4923417429809017348">इस पृष्ठ का एक अज्ञात भाषा से <ph name="LANGUAGE_LANGUAGE"/> में अनुवाद किया गया है</translation>
+<translation id="4923417429809017348">इस पृष्ठ का एक अज्ञात भाषा से <ph name="LANGUAGE_LANGUAGE" /> में अनुवाद किया गया है</translation>
<translation id="4926049483395192435">निर्दिष्ट किया जाना चाहिए.</translation>
<translation id="4968547170521245791">प्रॉक्‍सी नहीं कर सकते</translation>
-<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE"/> से <ph name="TARGET_LANGUAGE"/> में अनुवाद करें?</translation>
+<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE" /> से <ph name="TARGET_LANGUAGE" /> में अनुवाद करें?</translation>
<translation id="5019198164206649151">बैकिंग संग्रह खराब स्थिति में है</translation>
<translation id="5031870354684148875">Google अनुवाद के बारे में</translation>
+<translation id="5045550434625856497">गलत पासवर्ड</translation>
+<translation id="5087286274860437796">सर्वर का प्रमाण पत्र इस समय मान्य नहीं है.</translation>
<translation id="5089810972385038852">राज्य</translation>
+<translation id="5094747076828555589">यह सर्वर यह नहीं प्रमाणित कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र Chromium द्वारा विश्वसनीय नहीं है. ऐसा गलत कॉन्फ़िगरेशन या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="5095208057601539847">प्रांत</translation>
<translation id="5145883236150621069">नीति प्रतिसाद में त्रुटि कोड मौजूद है</translation>
<translation id="5172758083709347301">मशीन</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/> में नहीं है? इस त्रुटि की रिपोर्ट करें</translation>
+<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> में नहीं है? इस त्रुटि की रिपोर्ट करें</translation>
<translation id="5190835502935405962">बुकमार्क बार</translation>
+<translation id="5199729219167945352">प्रयोग</translation>
+<translation id="5251803541071282808">क्लाउड</translation>
<translation id="5295309862264981122">नेवीगेशन की दुबारा पूछें</translation>
<translation id="5299298092464848405">नीति पार्स करने में त्रुटि</translation>
+<translation id="5316812925700871227">घड़ी की विपरीत दिशा में घुमाएं</translation>
<translation id="5317780077021120954">सहेजें</translation>
<translation id="536296301121032821">नीति सेटिंग संग्रहीत करने में विफल</translation>
-<translation id="5439770059721715174">&quot;<ph name="ERROR_PATH"/>&quot; पर स्कीमा सत्यापन त्रुटि: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">यह सर्वर यह प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाण पत्र इस समय मान्य नहीं है. ऐसा गलत कॉन्फ़िगरेशन या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
+<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" पर स्कीमा सत्यापन त्रुटि: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">खराब नीति टाइमस्टैम्प</translation>
<translation id="5470861586879999274">&amp;संपादित करना फिर से करें</translation>
<translation id="5509780412636533143">प्रबंधित बुकमार्क</translation>
<translation id="5523118979700054094">नीति का नाम</translation>
<translation id="552553974213252141">क्या लेख सही तरीके से निकाला गया था?</translation>
<translation id="5540224163453853">अनुरोध किया गया लेख नहीं ढूंढा जा सका.</translation>
+<translation id="5556459405103347317">पुन: लोड करें</translation>
<translation id="5565735124758917034">सक्रिय</translation>
<translation id="560412284261940334">प्रबंधन समर्थित नहीं</translation>
<translation id="5629630648637658800">नीति सेटिंग लोड करने में विफल</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">वर्तमान उपयोगकर्ता</translation>
<translation id="5813119285467412249">&amp;जोड़ना फिर से करें</translation>
<translation id="5872918882028971132">अभिभावक सुझाव</translation>
-<translation id="587701087903783706">मोबाइल के अनुकूल दृश्‍य को बंद करें</translation>
<translation id="59107663811261420">कार्ड का यह प्रकार Google पेमेंट्स द्वारा इस व्यापारी के लिए समर्थित नहीं है. कृपया कोई भिन्न कार्ड चुनें.</translation>
+<translation id="5975083100439434680">ज़ूम आउट</translation>
<translation id="5989320800837274978">न तो कोई फ़िक्‍स्‍ड प्रॉक्‍सी सर्वर और न ही कोई .pac स्क्रिप्ट URL निर्दिष्ट किए गए हैं.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">बंद करें</translation>
+<translation id="6060685159320643512">सावधान, ये प्रयोग नुकसान पहुंचा सकते हैं</translation>
+<translation id="6151417162996330722">सर्वर प्रमाणपत्र की मान्‍यता अवधि बहुत लंबी है.</translation>
<translation id="6154808779448689242">वापस लौटे नीति टोकन का मिलान वर्तमान टोकन से नहीं होता</translation>
<translation id="6165508094623778733">अधिक जानें</translation>
<translation id="6259156558325130047">&amp;पुन: क्रमित करना फिर से करें</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> बुकमार्क</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> बुकमार्क</translation>
<translation id="6282194474023008486">डाक कोड</translation>
<translation id="6337534724793800597">नाम के अनुसार नीतियां फ़िल्टर करें</translation>
+<translation id="6387478394221739770">बेहतरीन नई Chrome सुविधाओं में रूचि है? chrome.com/beta पर हमारा बीटा चैनल आज़माएं.</translation>
+<translation id="6426993025560594914">आपके प्लेटफ़ॉर्म पर सभी प्रयोग उपलब्ध हैं!</translation>
<translation id="6445051938772793705">देश</translation>
<translation id="6458467102616083041">नीति के द्वारा डिफ़ॉल्‍ट खोज अक्षम कर दिए जाने के कारण उपेक्षित.</translation>
<translation id="647261751007945333">डिवाइस नीतियां</translation>
<translation id="6512448926095770873">इस पृष्ठ से जाएं</translation>
<translation id="6529602333819889595">&amp;हटाना फिर से करें</translation>
<translation id="6550675742724504774">विकल्प</translation>
-<translation id="6597614308054261376">आप <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> तक पहुंचने का प्रयास कर रहे हैं. यह पृष्‍ठ इस समय डेटा बचतकर्ता के द्वारा प्रॉक्‍सी नहीं किया जा सकता.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> खोज</translation>
+<translation id="6597614308054261376">आप <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> तक पहुंचने का प्रयास कर रहे हैं. यह पृष्‍ठ इस समय डेटा बचतकर्ता के द्वारा प्रॉक्‍सी नहीं किया जा सकता.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> खोज</translation>
<translation id="6644283850729428850">यह नीति हटा दी गई है.</translation>
<translation id="6646897916597483132">अपने कार्ड के सामने की ओर दिया गया 4 अंकों वाला CVC डालें</translation>
+<translation id="674375294223700098">अज्ञात सर्वर प्रमाणपत्र त्रुटि.</translation>
<translation id="6753269504797312559">नीति मान</translation>
<translation id="6831043979455480757">अनुवाद करें</translation>
<translation id="6839929833149231406">क्षेत्र</translation>
<translation id="6874604403660855544">&amp;जोड़ना फिर से करें</translation>
<translation id="6891596781022320156">नीति स्तर समर्थित नहीं है.</translation>
<translation id="6915804003454593391">उपयोगकर्ता:</translation>
+<translation id="6957887021205513506">सर्वर का प्रमाणपत्र फर्जी दिखाई देता है.</translation>
<translation id="6965382102122355670">ठीक</translation>
<translation id="6965978654500191972">डिवाइस</translation>
<translation id="6970216967273061347">जिला</translation>
<translation id="6973656660372572881">फ़िक्‍स्‍ड प्रॉक्‍सी सर्वर और .pac स्‍क्रिप्‍ट URL दोनों ही निर्दिष्ट हैं.</translation>
<translation id="6980028882292583085">JavaScript अलर्ट</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">आपने <ph name="DOMAIN" /> तक पहुंचने का प्रयास किया था, लेकिन सर्वर ने ऐसा प्रमाणपत्र प्रस्‍तुत किया जिसकी मान्‍यता अवधि विश्‍वसनीय होने के लिए बहुत लंबी है.</translation>
<translation id="7087282848513945231">काउंटी</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/> में अनुवाद विफल रहा.</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" /> में अनुवाद विफल रहा.</translation>
<translation id="7139724024395191329">अमीरात</translation>
+<translation id="7179921470347911571">अभी पुन: लॉन्‍च करें</translation>
<translation id="7180611975245234373">रीफ्रेश करें</translation>
<translation id="7182878459783632708">कोई नीति सेट नहीं की गई है</translation>
-<translation id="7186367841673660872">इस पृष्ठ का <ph name="ORIGINAL_LANGUAGE"/>से<ph name="LANGUAGE_LANGUAGE"/> में अनुवाद कर दिया गया है</translation>
+<translation id="7186367841673660872">इस पृष्ठ का <ph name="ORIGINAL_LANGUAGE" />से<ph name="LANGUAGE_LANGUAGE" /> में अनुवाद कर दिया गया है</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531"><ph name="SITE_NAME"/> पर <ph name="SEARCH_TERMS"/>के लिए खोजें</translation>
+<translation id="7208899522964477531"><ph name="SITE_NAME" /> पर <ph name="SEARCH_TERMS" />के लिए खोजें</translation>
+<translation id="725866823122871198"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से एक निजी कनेक्‍शन स्‍थापित नहीं किया जा सकता क्‍योंकि आपके कंप्‍यूटर का दिनांक और समय (<ph name="DATE_AND_TIME" />) गलत है.</translation>
<translation id="7275334191706090484">प्रबंधित बुकमार्क</translation>
<translation id="7298195798382681320">सुझाए गए</translation>
<translation id="7334320624316649418">&amp;पुन: क्रमित करना फिर से करें</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">आवश्यक</translation>
<translation id="7542995811387359312">स्वतः क्रेडिट कार्ड भरना अक्षम किया गया है क्योंकि यह फ़ॉर्म किसी सुरक्षित कनेक्शन का उपयोग नहीं करता है.</translation>
-<translation id="7568593326407688803">यह पृष्ठ<ph name="ORIGINAL_LANGUAGE"/>में है क्या आप इसका अनुवाद करना चाहेंगे?</translation>
+<translation id="7567204685887185387">यह सर्वर यह प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; हो सकता है इसका सुरक्षा प्रमाणपत्र धोखे से जारी किया गया हो. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
+<translation id="7568593326407688803">यह पृष्ठ<ph name="ORIGINAL_LANGUAGE" />में है क्या आप इसका अनुवाद करना चाहेंगे?</translation>
<translation id="7569952961197462199">Chrome से क्रेडिट कार्ड निकालें?</translation>
-<translation id="7600965453749440009">कभी भी <ph name="LANGUAGE"/> का अनुवाद न करें</translation>
-<translation id="7610193165460212391"><ph name="VALUE"/> मान सीमा से बाहर है.</translation>
+<translation id="7592362899630581445">सर्वर का प्रमाणपत्र नाम संबंधी प्रतिबंधों का उल्लंघन करता है.</translation>
+<translation id="7600965453749440009">कभी भी <ph name="LANGUAGE" /> का अनुवाद न करें</translation>
+<translation id="7610193165460212391"><ph name="VALUE" /> मान सीमा से बाहर है.</translation>
+<translation id="7674629440242451245">शानदार नई Chrome सुविधाओं में रूचि है? तो chrome.com/dev पर हमारा डेव चैनल आज़माएं.</translation>
<translation id="7752995774971033316">अप्रबंधित</translation>
+<translation id="7761701407923456692">सर्वर का प्रमाणपत्र URL से मेल नहीं हो रहा है.</translation>
<translation id="777702478322588152">प्रशासक प्रांत</translation>
<translation id="7791543448312431591">जोड़ें</translation>
<translation id="7805768142964895445">स्थिति</translation>
<translation id="7813600968533626083">Chrome से फ़ॉर्म सुझाव को निकालें?</translation>
<translation id="7887683347370398519">अपना CVC जांचें और पुन: प्रयास करें</translation>
<translation id="7935318582918952113">DOM डिस्टिलर</translation>
+<translation id="7938958445268990899">सर्वर का प्रमाणपत्र अभी तक मान्य नहीं है.</translation>
<translation id="7956713633345437162">मोबाइल बुकमार्क</translation>
<translation id="7961015016161918242">कभी नहीं</translation>
<translation id="7977590112176369853">&lt;क्वेरी प्रविष्ट करें&gt;</translation>
-<translation id="7983301409776629893">हमेशा <ph name="ORIGINAL_LANGUAGE"/> से <ph name="TARGET_LANGUAGE"/> में अनुवाद करें</translation>
+<translation id="7983301409776629893">हमेशा <ph name="ORIGINAL_LANGUAGE" /> से <ph name="TARGET_LANGUAGE" /> में अनुवाद करें</translation>
<translation id="7988324688042446538">डेस्कटॉप बुकमार्क</translation>
<translation id="7995512525968007366">निर्दिष्‍ट नहीं किया गया</translation>
-<translation id="8034522405403831421">यह पृष्ठ <ph name="SOURCE_LANGUAGE"/> में है. इसका <ph name="TARGET_LANGUAGE"/> में अनुवाद करें?</translation>
+<translation id="8003882219468422867">एंटरप्राइज़ ओवरराइड</translation>
+<translation id="8034522405403831421">यह पृष्ठ <ph name="SOURCE_LANGUAGE" /> में है. इसका <ph name="TARGET_LANGUAGE" /> में अनुवाद करें?</translation>
<translation id="8088680233425245692">लेख देखने में विफल रहा.</translation>
<translation id="8091372947890762290">सर्वर पर सक्रियण लंबित है</translation>
<translation id="8194797478851900357">&amp;ले जाना वापस लाएं</translation>
-<translation id="8201077131113104583">&quot;<ph name="EXTENSION_ID"/>&quot; आईडी वाले एक्‍सटेंशन का अमान्‍य अपडेट URL.</translation>
+<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" आईडी वाले एक्‍सटेंशन का अमान्‍य अपडेट URL.</translation>
<translation id="8208216423136871611">न सहेजें</translation>
<translation id="8218327578424803826">सौंपा गया स्‍थान:</translation>
<translation id="8249320324621329438">पिछली बार प्राप्त किया गया:</translation>
+<translation id="8294431847097064396">स्रोत</translation>
<translation id="8308427013383895095">नेटवर्क कनेक्शन में कोई समस्या होने के कारण अनुवाद विफल हुआ.</translation>
<translation id="8311778656528046050">क्‍या आप वाकई इस पृष्ठ को पुन: लोड करना चाहते हैं?</translation>
<translation id="8349305172487531364">बुकमार्क बार</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">इस पर लागू होती है</translation>
<translation id="8530504477309582336">कार्ड का यह प्रकार Google पेमेंट्स द्वारा समर्थित नहीं है. कृपया कोई भिन्न कार्ड चुनें.</translation>
<translation id="8553075262323480129">अनुवाद विफल हो गया क्योंकि पृष्ठ की भाषा निर्धारित नहीं की जा सकी.</translation>
-<translation id="8571890674111243710">पृष्ठ का अनुवाद <ph name="LANGUAGE"/> में कर रहा है...</translation>
+<translation id="8559762987265718583"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से एक निजी कनेक्‍शन स्‍थापित नहीं किया जा सकता क्‍योंकि आपके डिवाइस का दिनांक और समय (<ph name="DATE_AND_TIME" />) गलत है.</translation>
+<translation id="8571890674111243710">पृष्ठ का अनुवाद <ph name="LANGUAGE" /> में कर रहा है...</translation>
+<translation id="8647750283161643317">सभी को डिफ़ॉल्ट पर रीसेट करें</translation>
<translation id="8713130696108419660">खराब आरंभिक हस्ताक्षर</translation>
<translation id="8725066075913043281">पुन: प्रयास करें</translation>
+<translation id="8738058698779197622">सुरक्षित कनेक्‍शन स्‍थापित करने के लिए, आपकी घड़ी को ठीक से सेट किए जाने की आवश्‍यकता है. ऐसा इसलिए क्‍योंकि वेबसाइटों द्वारा स्‍वयं की पहचान करने के लिए उपयोग किए जाने वाले प्रमाण पत्र केवल विशिष्‍ट समयावधियों के लिए ही मान्‍य होते हैं. चूंकि आपके डिवाइस की घड़ी गलत है, इसलिए क्रोमियम इन प्रमाणपत्रों को सत्‍यापित नहीं कर सकता.</translation>
<translation id="8790007591277257123">&amp;हटाना फिर से करें</translation>
<translation id="8804164990146287819">गोपनीयता नीति</translation>
+<translation id="8820817407110198400">बुकमार्क</translation>
<translation id="8824019021993735287">Chrome इस समय आपका कार्ड सत्‍यापित नहीं कर सका. कृपया बाद में पुन: प्रयास करें.</translation>
<translation id="8834246243508017242">संपर्कों का स्वत:-भरण सक्षम करें…</translation>
<translation id="883848425547221593">अन्य बुकमार्क</translation>
+<translation id="884923133447025588">कोई निरस्तीकरण प्रक्रिया प्राप्त नहीं हुई.</translation>
<translation id="8866481888320382733">नीति सेटिंग पार्स करने में त्रुटि</translation>
<translation id="8876793034577346603">नेटवर्क कॉन्फ़िगरेशन पार्स होने में विफल रहा.</translation>
<translation id="8891727572606052622">अमान्य प्रॉक्सी मोड.</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/> आदेश चलाएं: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">क्षमा करें, यह प्रयोग आपके प्‍लेटफ़ॉर्म पर उपलब्ध नहीं है.</translation>
+<translation id="8903921497873541725">ज़ूम इन करें</translation>
+<translation id="8932102934695377596">आपकी घड़ी पीछे है</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" /> आदेश चलाएं: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">सर्वर के प्रमाणपत्र की समय-सीमा समाप्त हो चुकी है.</translation>
<translation id="8988760548304185580">अवधि समाप्‍ति दिनांक और अपने कार्ड के पीछे दिया गया 3 अंकों वाला CVC डालें</translation>
-<translation id="9020542370529661692">इस पृष्ठ का <ph name="TARGET_LANGUAGE"/> में अनुवाद कर दिया गया है</translation>
+<translation id="901974403500617787">सिस्टम-व्यापी रूप से लागू होने वाले फ़्लैग केवल स्वामी द्वारा ही सेट किए जा सकते हैं: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">इस पृष्ठ का <ph name="TARGET_LANGUAGE" /> में अनुवाद कर दिया गया है</translation>
+<translation id="9049981332609050619">आपने <ph name="DOMAIN" /> पर पहुंचने का प्रयास किया, लेकिन सर्वर ने एक अमान्‍य प्रमाणपत्र प्रस्तुत किया.</translation>
<translation id="9125941078353557812">अपने कार्ड के पीछे दिया गया 3 अंकों वाला CVC डालें</translation>
<translation id="9137013805542155359">मूल दिखाएं</translation>
<translation id="9148507642005240123">&amp;संपादन वापस लाएं</translation>
<translation id="9154176715500758432">इस पृष्ठ पर बनें रहें</translation>
<translation id="9170848237812810038">&amp;पूर्ववत् करें</translation>
+<translation id="917450738466192189">सर्वर का प्रमाणपत्र अमान्य है.</translation>
+<translation id="9187827965378254003">ओह, ऐसा लगता है कि वर्तमान में कोई प्रयोग उपलब्‍ध नहीं हैं.</translation>
<translation id="9207861905230894330">लेख जोड़ने में विफल रहा.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">फ़ॉर्म साफ़ करें</translation>
+<translation id="988159990683914416">डेवलपर बिल्ड</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_hr.xtb b/chromium/components/strings/components_strings_hr.xtb
index 1ca15c9256d..a8a4858c33a 100644
--- a/chromium/components/strings/components_strings_hr.xtb
+++ b/chromium/components/strings/components_strings_hr.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="hr">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hr">
+<translation id="1032854598605920125">Zakretanje u smjeru kazaljke na satu</translation>
<translation id="1055184225775184556">&amp;Poništi dodavanje</translation>
<translation id="106701514854093668">Oznake radne površine</translation>
-<translation id="1103523840287552314">Uvijek prevedi <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Prilagođavanje širini</translation>
+<translation id="1103523840287552314">Uvijek prevedi <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Poništi promjenu rasporeda</translation>
<translation id="111844081046043029">Jeste li sigurni da želite zatvoriti ovu stranicu?</translation>
<translation id="112840717907525620">Predmemorija pravila ispravna je</translation>
<translation id="1132774398110320017">Postavke Automatskog popunjavanja u Chromeu...</translation>
-<translation id="1152921474424827756">Pristupite <ph name="BEGIN_LINK"/>predmemoriranoj kopiji<ph name="END_LINK"/> stranice <ph name="URL"/></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="1152921474424827756">Pristupite <ph name="BEGIN_LINK" />predmemoriranoj kopiji<ph name="END_LINK" /> stranice <ph name="URL" /></translation>
+<translation id="121201262018556460">Pokušali ste doseći domenu <ph name="DOMAIN" />, ali poslužitelj je predstavio certifikat potpisan slabim ključem. Napadač je možda otkrio privatni ključ, a poslužitelj možda nije očekivani poslužitelj (možda ste u komunikaciji s napadačem).</translation>
<translation id="1227224963052638717">Nepoznato pravilo.</translation>
<translation id="1227633850867390598">Skrivanje vrijednosti</translation>
<translation id="1228893227497259893">Pogrešan identifikator entiteta</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Domena upisa:</translation>
<translation id="1344588688991793829">Postavke automatskog popunjavanja u Chromiumu...</translation>
<translation id="1426410128494586442">Da</translation>
+<translation id="1430915738399379752">Ispis</translation>
<translation id="1455235771979731432">Pojavio se problem prilikom potvrđivanja vaše kartice. Provjerite internetsku vezu i pokušajte ponovo.</translation>
<translation id="1491151370853475546">Ponovo učitaj ovu stranicu</translation>
<translation id="1549470594296187301">Za upotrebu te značajke mora biti omogućen JavaScript.</translation>
-<translation id="1639239467298939599">Učitavanje</translation>
<translation id="1640180200866533862">Korisnička pravila</translation>
<translation id="1644184664548287040">Mrežna konfiguracija nije važeća i nije ju bilo moguće uvesti.</translation>
-<translation id="1693754753824026215">Stranica na web-lokaciji <ph name="SITE"/> navodi sljedeće:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao jučer. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. Sat vašeg računala trenutačno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu.}one{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao prije # dan. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. Sat vašeg računala trenutačno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu.}few{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao prije # dana. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. Sat vašeg računala trenutačno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu.}other{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao prije # dana. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. Sat vašeg računala trenutačno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu.}}</translation>
+<translation id="168841957122794586">Certifikat poslužitelja sadrži slab kriptografski ključ!</translation>
+<translation id="1693754753824026215">Stranica na web-lokaciji <ph name="SITE" /> navodi sljedeće:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; operativni sustav vašeg uređaja smatra da njegov sigurnosni certifikat nije pouzdan. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
<translation id="1821930232296380041">Nevažeći zahtjev ili parametri zahtjeva</translation>
-<translation id="1853748787962613237">Prikaz članka nije uspio.</translation>
<translation id="1871208020102129563">Proxy poslužitelj postavljen je na upotrebu fiksnih proxy poslužitelja, a ne URL .pac skripte.</translation>
-<translation id="1875753206475436906">vrsta heuristike: <ph name="HEURISTIC_TYPE"/>
- vrsta poslužitelja: <ph name="SERVER_TYPE"/>
- potpis polja: <ph name="FIELD_SIGNATURE"/>
- potpis obrasca: <ph name="FORM_SIGNATURE"/>
- id eksperimenta: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Posjetite <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Oznake s domene <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Posjetite <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Oznake s domene <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Pogreška postavljanja u seriju</translation>
+<translation id="1974060860693918893">Napredno</translation>
<translation id="2025186561304664664">Proxy je postavljen na automatsko konfiguriranje.</translation>
<translation id="2025623846716345241">Potvrda ponovnog učitavanja</translation>
-<translation id="2030481566774242610">Jeste li mislili <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Jeste li mislili <ph name="LINK" />?</translation>
<translation id="2053553514270667976">ZIP kôd</translation>
<translation id="20817612488360358">Postavljena je upotreba sistemskih postavki proxy poslužitelja, ali također je određena izričita konfiguracija proxy poslužitelja.</translation>
<translation id="2094505752054353250">Domena se ne podudara</translation>
<translation id="2096368010154057602">Departman</translation>
<translation id="2113977810652731515">Kartica</translation>
-<translation id="2114841414352855701">Zanemareno jer je nadjačano pravilom <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Zanemareno jer je nadjačano pravilom <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Lokalni klijent</translation>
<translation id="213826338245044447">Mobilne oznake</translation>
+<translation id="2171101176734966184">Pokušali ste doseći domenu <ph name="DOMAIN" />, ali poslužitelj je predstavio certifikat potpisan slabim algoritmom potpisa. Znači da su sigurnosne vjerodajnice koje je poslužitelj predstavio možda krivotvorene, a poslužitelj možda nije poslužitelj koji očekujete (možda ste u komunikaciji s napadačem).</translation>
<translation id="2181821976797666341">Pravila</translation>
<translation id="2212735316055980242">Pravilo nije pronađeno</translation>
<translation id="2213606439339815911">Dohvaćanje unosa...</translation>
<translation id="225207911366869382">Ta je vrijednost obustavljena za to pravilo.</translation>
<translation id="2262243747453050782">HTTP pogreška</translation>
-<translation id="2270192940992995399">Članak nije pronađen.</translation>
-<translation id="2328300916057834155">Zanemarena nevažeća oznaka u indeksu <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Nedostupni eksperimenti</translation>
+<translation id="229702904922032456">Korijenski ili posrednički certifikat je istekao.</translation>
+<translation id="2328300916057834155">Zanemarena nevažeća oznaka u indeksu <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Druge oznake</translation>
<translation id="2359808026110333948">Nastavi</translation>
<translation id="2367567093518048410">Razina</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="2396249848217231973">&amp;Poništi brisanje</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="2455981314101692989">Ova web-stranica ima onemogućeno automatsko popunjavanje za taj obrazac.</translation>
<translation id="2479410451996844060">Nevažeći URL pretraživanja.</translation>
+<translation id="2491120439723279231">Certifikat poslužitelja sadrži pogreške.</translation>
<translation id="2495083838625180221">Raščlanjivanje JSON datoteka</translation>
<translation id="2498091847651709837">Skeniraj novu karticu</translation>
<translation id="2556876185419854533">&amp;Poništi uređivanje</translation>
-<translation id="2581221116934462656">Želite li da <ph name="PRODUCT_NAME"/> sljedeći put ponudi prijevod stranica ove web-lokacije na <ph name="LANGUAGE_NAME"/>?</translation>
+<translation id="2581221116934462656">Želite li da <ph name="PRODUCT_NAME" /> sljedeći put ponudi prijevod stranica ove web-lokacije na <ph name="LANGUAGE_NAME" />?</translation>
<translation id="2587841377698384444">ID API-ja direktorija:</translation>
<translation id="2597378329261239068">Ovaj je dokument zaštićen zaporkom. Unesite zaporku.</translation>
+<translation id="2625385379895617796">Sat ide unaprijed</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2653659639078652383">Pošalji</translation>
<translation id="2704283930420550640">Vrijednost ne odgovara formatu.</translation>
<translation id="2721148159707890343">Zahtjev je uspio</translation>
+<translation id="2728127805433021124">Certifikat poslužitelja potpisan je slabim algoritmom potpisa.</translation>
<translation id="2774256287122201187">Možete nastaviti. Ako otvorite stranicu, to će se upozorenje pojaviti tek za pet minuta.</translation>
<translation id="277499241957683684">Zapis uređaja nije prisutan</translation>
<translation id="2835170189407361413">Obriši obrazac</translation>
-<translation id="2855922900409897335">Potvrda kreditne kartice <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Potvrda kreditne kartice <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Poslužitelj nije mogao dokazati da se radi o domeni <ph name="DOMAIN" />. Njezin je sigurnosni certifikat istekao. Uzrok može biti pogrešna konfiguracija ili napadač koji ometa vašu vezu. Sat vašeg računala trenutačno je postavljen na <ph name="CURRENT_TIME" />. Je li to u redu? Ako nije, podesite sat svog sustava, a zatim osvježite ovu stranicu.</translation>
+<translation id="2922350208395188000">Certifikat poslužitelja nije moguće provjeriti.</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="2958431318199492670">Mrežna konfiguracija nije u skladu sa standardima ONC. Dijelove konfiguracije nije moguće uvesti.</translation>
<translation id="2972581237482394796">&amp;Vrati poništeno</translation>
-<translation id="3010559122411665027">Unos popisa &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Unos popisa "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Pogrešna vrsta pravila</translation>
<translation id="3105172416063519923">ID uređaja:</translation>
<translation id="3145945101586104090">Dekodiranje odgovora nije uspjelo</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Otok</translation>
<translation id="3219579145727097045">Unesite datum isteka i četveroznamenkasti CVC s prednje strane kartice</translation>
-<translation id="3228969707346345236">Prijevod nije uspio jer stranica već je na jeziku: <ph name="LANGUAGE"/>.</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="3228969707346345236">Prijevod nije uspio jer stranica već je na jeziku: <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Poništi promjenu rasporeda</translation>
+<translation id="3286538390144397061">Ponovo pokreni sad</translation>
<translation id="333371639341676808">Spriječite ovu stranicu od stvaranja dodatnih dijaloga.</translation>
-<translation id="3369366829301677151">Ažurirajte i potvrdite karticu <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">postavke</translation>
+<translation id="3369192424181595722">Pogreška sata</translation>
+<translation id="3369366829301677151">Ažurirajte i potvrdite karticu <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Dodjela je uklonjena</translation>
<translation id="3377188786107721145">Pogreška pri analizi pravila</translation>
<translation id="3380365263193509176">Nepoznata pogreška</translation>
<translation id="3380864720620200369">ID klijenta:</translation>
<translation id="3427342743765426898">&amp;Ponovi uređivanje</translation>
+<translation id="3435896845095436175">Omogući</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Dohvati interval:</translation>
+<translation id="3462200631372590220">Sakrij napredno</translation>
+<translation id="3528171143076753409">Certifikat poslužitelja nije pouzdan.</translation>
<translation id="3542684924769048008">Upotrijebite zaporku za:</translation>
<translation id="3583757800736429874">&amp;Ponovi premještanje</translation>
<translation id="3623476034248543066">Prikaži vrijednost</translation>
+<translation id="3648607100222897006">Te eksperimentalne značajke mogu se promijeniti, pokvariti ili nestati u bilo kojem trenutku. Ne dajemo apsolutno nikakva jamstva o tome što se može dogoditi ako uključite jedan od tih eksperimenata, a vaš preglednik čak može spontano sagorjeti. Šalu na stranu, vaš preglednik može izbrisati sve vaše podatke ili vaša sigurnost i privatnost mogu biti ugrožene na neočekivane načine. Svi eksperimenti koje omogućite bit će omogućeni za sve korisnike ovog preglednika. Nastavite uz oprez.</translation>
<translation id="3650584904733503804">Valjanost je uspješna</translation>
<translation id="370665806235115550">Učitavanje...</translation>
<translation id="3712624925041724820">Licence su potrošene</translation>
<translation id="3739623965217189342">Veza koju ste kopirali</translation>
<translation id="375403751935624634">Prijevod nije uspio zbog poslužiteljske pogreške.</translation>
<translation id="385051799172605136">Natrag</translation>
+<translation id="3858027520442213535">Ažuriraj datum i vrijeme</translation>
<translation id="3884278016824448484">Identifikator uređaja sukobljen je</translation>
<translation id="3885155851504623709">Župa</translation>
<translation id="3934680773876859118">Učitavanje dokumenta PDF nije uspjelo</translation>
<translation id="3963721102035795474">Način čitača</translation>
<translation id="4030383055268325496">&amp;Poništi dodavanje</translation>
-<translation id="4058922952496707368">Stavka &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">UPOZORENJE</translation>
+<translation id="4058922952496707368">Stavka "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Konfiguracija proxy poslužitelja postavljena je za upotrebu URL-a .pac skripte, a ne fiksnih proxy poslužitelja.</translation>
<translation id="409504436206021213">Ne učitavaj ponovo</translation>
<translation id="4103249731201008433">Serijski broj uređaja nije važeći</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Potpis nije valjan</translation>
<translation id="4269787794583293679">(Nema korisničkog imena)</translation>
<translation id="4300246636397505754">Nadređeni prijedlozi</translation>
-<translation id="4372948949327679948">Očekivana vrijednost vrste <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Članak nije pronađen</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="4394049700291259645">Onemogući</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="443673843213245140">Upotreba proxy poslužitelja onemogućena je, ali određena je izričita konfiguracija proxy poslužitelja.</translation>
-<translation id="4506176782989081258">Pogreška pri provjeri valjanosti: <ph name="VALIDATION_ERROR"/>.</translation>
+<translation id="4506176782989081258">Pogreška pri provjeri valjanosti: <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4587425331216688090">Želite li s Chromea ukloniti adresu?</translation>
<translation id="4594403342090139922">&amp;Poništi brisanje</translation>
<translation id="4607653538520819196">Ušteda podataka ne može obraditi stranicu putem proxyja.</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="4726672564094551039">Ponovo učitaj pravila</translation>
+<translation id="4728558894243024398">Platforma</translation>
+<translation id="4771973620359291008">Došlo je do nepoznate pogreške.</translation>
<translation id="4800132727771399293">Provjerite datum isteka i CVC pa pokušajte ponovo</translation>
<translation id="4813512666221746211">Pogreška mreže</translation>
+<translation id="4816492930507672669">Prilagodi stranici</translation>
<translation id="4850886885716139402">Prikaz</translation>
-<translation id="4923417429809017348">Ova je stranica prevedena s nepoznatog jezika na <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Ova je stranica prevedena s nepoznatog jezika na <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Mora biti određeno.</translation>
<translation id="4968547170521245791">Nije moguća obrada putem proxyja</translation>
-<translation id="498957508165411911">Želite li prijevod s jezika <ph name="ORIGINAL_LANGUAGE"/> na <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Želite li prijevod s jezika <ph name="ORIGINAL_LANGUAGE" /> na <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Sigurnosno pohranjivanje u neispravnom je stanju</translation>
<translation id="5031870354684148875">O Google Prevoditelju</translation>
+<translation id="5045550434625856497">Netočna zaporka</translation>
+<translation id="5087286274860437796">Certifikat poslužitelja trenutačno nije važeći.</translation>
<translation id="5089810972385038852">Država</translation>
+<translation id="5094747076828555589">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; Chromium smatra da njegov sigurnosni certifikat nije pouzdan. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
<translation id="5095208057601539847">Provincija</translation>
<translation id="5145883236150621069">Odgovor na pravilo sadrži kôd pogreške</translation>
<translation id="5172758083709347301">Strojno</translation>
-<translation id="5179510805599951267">Nije <ph name="ORIGINAL_LANGUAGE"/> jezik? Prijavite tu pogrešku</translation>
+<translation id="5179510805599951267">Nije <ph name="ORIGINAL_LANGUAGE" /> jezik? Prijavite tu pogrešku</translation>
<translation id="5190835502935405962">Traka oznaka</translation>
+<translation id="5199729219167945352">Eksperimenti</translation>
+<translation id="5251803541071282808">Oblak</translation>
<translation id="5295309862264981122">Potvrdi navigaciju</translation>
<translation id="5299298092464848405">Pogreška u pravilu analize</translation>
+<translation id="5316812925700871227">Zakretanje u suprotnom smjeru od kazaljke na satu</translation>
<translation id="5317780077021120954">Spremi</translation>
<translation id="536296301121032821">Pohrana postavki pravila nije uspjela</translation>
-<translation id="5439770059721715174">Pogreška provjere sheme na lokaciji &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Pogreška provjere sheme na lokaciji "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Vremenska oznaka pravila koje nije valjano</translation>
<translation id="5470861586879999274">&amp;Ponovi uređivanje</translation>
<translation id="5509780412636533143">Upravljane oznake</translation>
<translation id="5523118979700054094">Naziv pravila</translation>
<translation id="552553974213252141">Je li tekst ispravno izdvojen?</translation>
<translation id="5540224163453853">Traženi članak nije pronađen.</translation>
+<translation id="5556459405103347317">Ponovno učitaj</translation>
<translation id="5565735124758917034">Aktivno</translation>
<translation id="560412284261940334">Upravljanje nije podržano</translation>
<translation id="5629630648637658800">Učitavanje postavki pravila nije uspjelo</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Trenutačni korisnik:</translation>
<translation id="5813119285467412249">&amp;Ponovi dodavanje</translation>
<translation id="5872918882028971132">Nadređeni prijedlozi</translation>
-<translation id="587701087903783706">Zatvori prikaz prilagođen mobilnim uređajima</translation>
<translation id="59107663811261420">Google Payments ne podržava tu vrstu kartice za ovog trgovca. Odaberite neku drugu karticu.</translation>
+<translation id="5975083100439434680">Smanji</translation>
<translation id="5989320800837274978">Nisu određeni fiksni proxy poslužitelji ni URL .pac skripte.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Zatvori</translation>
+<translation id="6060685159320643512">Oprez, ovi eksperimenti mogu ugristi</translation>
+<translation id="6151417162996330722">Certifikat poslužitelja ima predugo razdoblje valjanosti.</translation>
<translation id="6154808779448689242">Vraćeni token pravila ne odgovara trenutačnom tokenu</translation>
<translation id="6165508094623778733">Saznajte više</translation>
<translation id="6259156558325130047">&amp;Ponovi promjenu rasporeda</translation>
-<translation id="6263376278284652872">Oznake domene <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Oznake domene <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Poštanski broj</translation>
<translation id="6337534724793800597">Filtriranje pravila prema nazivu</translation>
+<translation id="6387478394221739770">Zanimaju li vas nove, kul značajke preglednika Chrome? Isprobajte naš beta kanal na stranici chrome.com/beta.</translation>
+<translation id="6426993025560594914">Svi su eksperimenti dostupni na vašoj platformi!</translation>
<translation id="6445051938772793705">Zemlja</translation>
<translation id="6458467102616083041">Zanemareno jer je zadano pretraživanje onemogućeno pravilom.</translation>
<translation id="647261751007945333">Pravila uređaja</translation>
<translation id="6512448926095770873">Zatvori ovu stranicu</translation>
<translation id="6529602333819889595">&amp;Ponovi brisanje</translation>
<translation id="6550675742724504774">Opcije</translation>
-<translation id="6597614308054261376">Pokušavate pristupiti web-stranici <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Ušteda podataka trenutačno ne može obraditi tu stranicu putem proxyja.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Pretraživanje</translation>
+<translation id="6597614308054261376">Pokušavate pristupiti web-stranici <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Ušteda podataka trenutačno ne može obraditi tu stranicu putem proxyja.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Pretraživanje</translation>
<translation id="6644283850729428850">Ovo je pravilo zastarjelo.</translation>
<translation id="6646897916597483132">Unesite četveroznamenkasti CVC s prednje strane kartice</translation>
+<translation id="674375294223700098">Nepoznata pogreška certifikata poslužitelja</translation>
<translation id="6753269504797312559">Vrijednost pravila</translation>
<translation id="6831043979455480757">Prevedi</translation>
<translation id="6839929833149231406">Područje</translation>
<translation id="6874604403660855544">&amp;Ponovi dodavanje</translation>
<translation id="6891596781022320156">Razina pravila nije podržana.</translation>
<translation id="6915804003454593391">Korisnik:</translation>
+<translation id="6957887021205513506">Certifikat poslužitelja izgleda kao falsifikat.</translation>
<translation id="6965382102122355670">U redu</translation>
<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="6980028882292583085">JavaScript upozorenje</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Pokušali ste pristupiti domeni <ph name="DOMAIN" />, ali je poslužitelj pružio certifikat koji nije pouzdan zbog predugog razdoblja valjanosti.</translation>
<translation id="7087282848513945231">Županija</translation>
-<translation id="7108649287766967076">Prijevod na <ph name="TARGET_LANGUAGE"/> nije uspio.</translation>
+<translation id="7108649287766967076">Prijevod na <ph name="TARGET_LANGUAGE" /> nije uspio.</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7179921470347911571">Ponovo pokreni sada</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="7186367841673660872">Ova je stranica prevedena s jezika<ph name="ORIGINAL_LANGUAGE" />na<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Pretraži <ph name="SITE_NAME"/> za <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Pretraži <ph name="SITE_NAME" /> za <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Sigurnu vezu s domenom <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nije moguće uspostaviti jer datum i vrijeme na računalu (<ph name="DATE_AND_TIME" />) nisu točni.</translation>
<translation id="7275334191706090484">Upravljane oznake</translation>
<translation id="7298195798382681320">Preporučeno</translation>
<translation id="7334320624316649418">&amp;Ponovi promjenu rasporeda</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obavezno</translation>
<translation id="7542995811387359312">Automatsko popunjavanje kreditne kartice onemogućeno je jer se ovaj obrazac ne služi sigurnom vezom.</translation>
-<translation id="7568593326407688803">Ova je stranica na ovom jeziku:<ph name="ORIGINAL_LANGUAGE"/>Želite li je prevesti?</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="7568593326407688803">Ova je stranica na ovom jeziku:<ph name="ORIGINAL_LANGUAGE" />Želite li je prevesti?</translation>
<translation id="7569952961197462199">Želite li s Chromea ukloniti kreditnu karticu?</translation>
-<translation id="7600965453749440009">Nikad ne prevodi <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Vrijednost je izvan raspona <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Certifikat poslužitelja krši ograničenja naziva.</translation>
+<translation id="7600965453749440009">Nikad ne prevodi <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Vrijednost je izvan raspona <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Zanimaju li vas nove, kul značajke preglednika Chrome? Isprobajte naš razvojni kanal na stranici chrome.com/dev.</translation>
<translation id="7752995774971033316">Nema upravitelja</translation>
+<translation id="7761701407923456692">Certifikat poslužitelja ne podudara se s URL-om.</translation>
<translation id="777702478322588152">Prefektura</translation>
<translation id="7791543448312431591">Dodaj</translation>
<translation id="7805768142964895445">Status</translation>
<translation id="7813600968533626083">Želite li s Chromea ukloniti prijedlog za obrasce?</translation>
<translation id="7887683347370398519">Provjerite CVC i pokušajte ponovo</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Certifkat poslužitelja još nije valjan.</translation>
<translation id="7956713633345437162">Mobilne oznake</translation>
<translation id="7961015016161918242">Nikad</translation>
<translation id="7977590112176369853">&lt;unesite upit&gt;</translation>
-<translation id="7983301409776629893">Uvijek prevedi <ph name="ORIGINAL_LANGUAGE"/> na <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Uvijek prevedi <ph name="ORIGINAL_LANGUAGE" /> na <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Oznake radne površine</translation>
<translation id="7995512525968007366">Nije navedeno</translation>
-<translation id="8034522405403831421">Jezik ove stranice jest <ph name="SOURCE_LANGUAGE"/>. Želite li je prevesti na <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Pravilo organizacije koje se ne može nadjačati</translation>
+<translation id="8034522405403831421">Jezik ove stranice jest <ph name="SOURCE_LANGUAGE" />. Želite li je prevesti na <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Prikaz članka nije uspio.</translation>
<translation id="8091372947890762290">Aktivacija je na čekanju na poslužitelju</translation>
<translation id="8194797478851900357">&amp;Poništi premještanje</translation>
-<translation id="8201077131113104583">Nevažeći URL ažuriranja za proširenje s ID-om &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">Nevažeći URL ažuriranja za proširenje s ID-om "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Ne spremaj</translation>
<translation id="8218327578424803826">Dodijeljena lokacija:</translation>
<translation id="8249320324621329438">Zadnje dohvaćanje:</translation>
+<translation id="8294431847097064396">Izvor</translation>
<translation id="8308427013383895095">Prijevod nije uspio zbog problema s mrežnom vezom.</translation>
<translation id="8311778656528046050">Jeste li sigurni da želite ponovo učitati ovu stranicu?</translation>
<translation id="8349305172487531364">Traka oznaka</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Primjenjuje se na</translation>
<translation id="8530504477309582336">Google Payments ne podržava tu vrstu kartice. Odaberite neku drugu karticu.</translation>
<translation id="8553075262323480129">Prijevod nije uspio jer nije bilo moguće odrediti jezik stranice.</translation>
-<translation id="8571890674111243710">Prijevod stranice na <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Sigurnu vezu s domenom <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nije moguće uspostaviti jer datum i vrijeme (<ph name="DATE_AND_TIME" />) na vašem uređaju nisu točni.</translation>
+<translation id="8571890674111243710">Prijevod stranice na <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Vrati sve na zadano</translation>
<translation id="8713130696108419660">Pogrešan početni potpis</translation>
<translation id="8725066075913043281">Pokušajte ponovo</translation>
+<translation id="8738058698779197622">Za uspostavu sigurne veze sat mora biti točno postavljen. To je zato što certifikati koje web-lokacije upotrebljavaju za međusobnu identifikaciju vrijede samo određeno vrijeme. Budući da sat na vašem uređaju nije točan, Chromium ne može potvrditi te certifikate.</translation>
<translation id="8790007591277257123">&amp;Ponovi brisanje</translation>
<translation id="8804164990146287819">Pravila o privatnosti</translation>
+<translation id="8820817407110198400">Knjižne oznake</translation>
<translation id="8824019021993735287">Chrome nije uspio potvrditi vašu karticu u ovom trenutku. Pokušajte ponovo kasnije.</translation>
<translation id="8834246243508017242">Omogući Automatsko popunjavanje pomoću Kontakata...</translation>
<translation id="883848425547221593">Druge oznake</translation>
+<translation id="884923133447025588">Nije pronađen mehanizam za opoziv.</translation>
<translation id="8866481888320382733">Pogreška pri analizi postavki pravila</translation>
<translation id="8876793034577346603">Mrežna konfiguracija nije uspješno analizirana.</translation>
<translation id="8891727572606052622">Nevažeći način proxy poslužitelja.</translation>
-<translation id="8940229512486821554">Pokretanje proširenja <ph name="EXTENSION_NAME"/> za naredbu: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Nažalost, ovaj eksperiment nije dostupan na vašoj platformi.</translation>
+<translation id="8903921497873541725">Povećaj</translation>
+<translation id="8932102934695377596">Sat kasni</translation>
+<translation id="8940229512486821554">Pokretanje proširenja <ph name="EXTENSION_NAME" /> za naredbu: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Istekao je certifikat poslužitelja.</translation>
<translation id="8988760548304185580">Unesite datum isteka i troznamenkasti CVC s poleđine kartice</translation>
-<translation id="9020542370529661692">Ova je stranica prevedena na <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Oznake koje se primjenjuju na razini sustava može postaviti samo vlasnik: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Ova je stranica prevedena na <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Pokušali ste pristupiti domeni <ph name="DOMAIN" />, ali poslužitelj je prikazao nevažeći certifikat.</translation>
<translation id="9125941078353557812">Unesite troznamenkasti CVC s prednje strane kartice</translation>
<translation id="9137013805542155359">Prikaži original</translation>
<translation id="9148507642005240123">&amp;Poništi uređivanje</translation>
<translation id="9154176715500758432">Ostani na ovoj stranici</translation>
<translation id="9170848237812810038">&amp;Poništi</translation>
+<translation id="917450738466192189">Certifikat poslužitelja nije valjan.</translation>
+<translation id="9187827965378254003">Ajoj, čini se da trenutno nema dostupnih pokusa.</translation>
<translation id="9207861905230894330">Dodavanje članka nije uspjelo.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">IZBRIŠI OBRAZAC</translation>
+<translation id="988159990683914416">Sastavak razvojnog programera</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_hu.xtb b/chromium/components/strings/components_strings_hu.xtb
index 78d4f9ffaf4..2480a504cb6 100644
--- a/chromium/components/strings/components_strings_hu.xtb
+++ b/chromium/components/strings/components_strings_hu.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="hu">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hu">
+<translation id="1032854598605920125">Forgatás jobbra</translation>
<translation id="1055184225775184556">&amp;Hozzáadás visszavonása</translation>
<translation id="106701514854093668">Asztali könyvjelzők</translation>
-<translation id="1103523840287552314"><ph name="LANGUAGE"/> - mindig legyen lefordítva</translation>
+<translation id="1080116354587839789">Szélességhez igazítás</translation>
+<translation id="1103523840287552314"><ph name="LANGUAGE" /> - mindig legyen lefordítva</translation>
<translation id="1113869188872983271">&amp;Átrendezés visszavonása</translation>
<translation id="111844081046043029">Biztos, hogy el szeretné hagyni ezt az oldalt?</translation>
<translation id="112840717907525620">Irányelv-gyorsítótár OK</translation>
<translation id="1132774398110320017">A Chrome Automatikus kitöltési beállításai…</translation>
-<translation id="1152921474424827756">A(z) <ph name="URL"/> egy <ph name="BEGIN_LINK"/>tárolt változatának<ph name="END_LINK"/> megtekintése</translation>
+<translation id="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="1152921474424827756">A(z) <ph name="URL" /> egy <ph name="BEGIN_LINK" />tárolt változatának<ph name="END_LINK" /> megtekintése</translation>
+<translation id="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="1227224963052638717">Ismeretlen házirend</translation>
<translation id="1227633850867390598">Érték elrejtése</translation>
<translation id="1228893227497259893">Helytelen entitásazonosító</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Regisztrációs domain:</translation>
<translation id="1344588688991793829">A Chromium Automatikus kitöltési beállításai…</translation>
<translation id="1426410128494586442">Igen</translation>
+<translation id="1430915738399379752">Nyomtatás</translation>
<translation id="1455235771979731432">A kártya ellenőrzése során hiba történt. Ellenőrizze az internetkapcsolatot, és próbálja újra.</translation>
<translation id="1491151370853475546">Az oldal újratöltése</translation>
<translation id="1549470594296187301">A funkció használatához engedélyezni kell a JavaScriptet.</translation>
-<translation id="1639239467298939599">Betöltés</translation>
<translation id="1640180200866533862">Felhasználói házirendek</translation>
<translation id="1644184664548287040">A hálózati konfiguráció érvénytelen és nem importálható.</translation>
-<translation id="1693754753824026215">A <ph name="SITE"/> webhelyen lévő oldal közlendője:</translation>
+<translation id="1655462015569774233">{1,plural, =1{A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa tegnap lejárt. Ennek oka lehet konfigurációs hiba, de az is lehet, hogy egy támadó eltérítette az Ön kapcsolódását. Számítógépének órája jelenleg a következőre van állítva: <ph name="CURRENT_DATE" />. Ez megfelelőnek tűnik? Ha nem, állítsa be megfelelően a rendszer óráját, majd frissítse az oldalt.}other{A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa # nappal ezelőtt lejárt. Ennek oka lehet konfigurációs hiba, de az is lehet, hogy egy támadó eltérítette az Ön kapcsolódását. Számítógépének órája jelenleg a következőre van állítva: <ph name="CURRENT_DATE" />. Ez megfelelőnek tűnik? Ha nem, állítsa be megfelelően a rendszer óráját, majd frissítse az oldalt.}}</translation>
+<translation id="168841957122794586">A szervertanúsítvány gyenge titkosítási kulcsot tartalmaz.</translation>
+<translation id="1693754753824026215">A <ph name="SITE" /> webhelyen lévő oldal közlendője:</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="1734864079702812349">American Express</translation>
+<translation id="1763864636252898013">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa az Ön eszközének operációs rendszere szerint nem megbízható. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását.</translation>
<translation id="1821930232296380041">Érvénytelen kérés vagy kérésparaméter</translation>
-<translation id="1853748787962613237">Nem sikerült megjeleníteni a cikket.</translation>
<translation id="1871208020102129563">A proxy fix proxyszerverek használatára van beállítva, nem pedig .pac típusú szkript URL címének használatára.</translation>
-<translation id="1875753206475436906">heurisztika típusa: <ph name="HEURISTIC_TYPE"/>
- szerver típusa: <ph name="SERVER_TYPE"/>
- mező aláírása: <ph name="FIELD_SIGNATURE"/>
- űrlap aláírása: <ph name="FORM_SIGNATURE"/>
- kísérlet azonosítója: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Ugrás ide: <ph name="LINK"/></translation>
-<translation id="1962204205936693436">A(z) <ph name="DOMAIN"/> könyvjelzői</translation>
+<translation id="194030505837763158">Ugrás ide: <ph name="LINK" /></translation>
+<translation id="1962204205936693436">A(z) <ph name="DOMAIN" /> könyvjelzői</translation>
<translation id="1973335181906896915">Szerializálási hiba</translation>
+<translation id="1974060860693918893">Speciális</translation>
<translation id="2025186561304664664">Automatikusan konfigurálhatóra beállított proxy.</translation>
<translation id="2025623846716345241">Újratöltés megerősítése</translation>
-<translation id="2030481566774242610">Erre gondolt: <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Erre gondolt: <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Irányítószám</translation>
<translation id="20817612488360358">A rendszer proxybeállításai konfigurálva vannak a használathoz, de kifejezett proxykonfiguráció is meg van adva.</translation>
<translation id="2094505752054353250">Domainkeveredés</translation>
<translation id="2096368010154057602">Megye</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="2114841414352855701">A rendszer figyelmen kívül hagyja, mivel a(z) <ph name="POLICY_NAME" /> felülírta.</translation>
+<translation id="2128531968068887769">Natív kliens</translation>
<translation id="213826338245044447">Mobil könyvjelzők</translation>
+<translation id="2171101176734966184">Megpróbálta elérni a(z) <ph name="DOMAIN" /> webhelyet, de a szerver egy gyenge aláírási algoritmust használó tanúsítványt adott. Ez alapján elképzelhető, hogy a szerver által megadott biztonsági tanúsítványt meghamisították, és a szerver nem az, amelyikre számított (lehet, hogy éppen egy támadóval kommunikál).</translation>
<translation id="2181821976797666341">Házirendek</translation>
<translation id="2212735316055980242">Nem találhatók irányelvek</translation>
<translation id="2213606439339815911">Bejegyzések lekérése...</translation>
<translation id="225207911366869382">Ez az érték elavult ennél a házirendnél.</translation>
<translation id="2262243747453050782">HTTP hiba</translation>
-<translation id="2270192940992995399">Nem sikerült megtalálni a cikket.</translation>
-<translation id="2328300916057834155">Mellőzött érvénytelen könyvjelző a(z) <ph name="ENTRY_INDEX"/>. indexnél</translation>
+<translation id="2282872951544483773">Nem elérhető kísérletek</translation>
+<translation id="229702904922032456">Lejárt egy gyökér- vagy köztes tanúsítvány.</translation>
+<translation id="2328300916057834155">Mellőzött érvénytelen könyvjelző a(z) <ph name="ENTRY_INDEX" />. indexnél</translation>
<translation id="2354001756790975382">További könyvjelzők</translation>
<translation id="2359808026110333948">Folytatás</translation>
<translation id="2367567093518048410">Szint</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="2396249848217231973">&amp;Törlés visszavonása</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="2455981314101692989">A weboldal letiltotta az automatikus kitöltést erre az űrlapra.</translation>
<translation id="2479410451996844060">Érvénytelen keresési URL</translation>
+<translation id="2491120439723279231">A szervezet tanúsítványa hibákat tartalmaz.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2498091847651709837">Új kártya beolvasása</translation>
<translation id="2556876185419854533">&amp;Szerkesztés visszavonása</translation>
-<translation id="2581221116934462656">Szeretné, hogy a(z) <ph name="PRODUCT_NAME"/> legközelebb felajánlja a webhely <ph name="LANGUAGE_NAME"/> nyelvű oldalainak lefordítását?</translation>
+<translation id="2581221116934462656">Szeretné, hogy a(z) <ph name="PRODUCT_NAME" /> legközelebb felajánlja a webhely <ph name="LANGUAGE_NAME" /> nyelvű oldalainak lefordítását?</translation>
<translation id="2587841377698384444">Könyvtár API-azonosítója:</translation>
<translation id="2597378329261239068">Ez a dokumentum jelszóval védett. Kérjük, adja meg a jelszót.</translation>
+<translation id="2625385379895617796">Az órája siet</translation>
<translation id="2639739919103226564">Állapot:</translation>
+<translation id="2653659639078652383">Elküldés</translation>
<translation id="2704283930420550640">Az érték nem egyezik a formátummal.</translation>
<translation id="2721148159707890343">Sikeres kérés</translation>
+<translation id="2728127805433021124">A szerver tanúsítványa gyenge aláírási algoritmussal van aláírva.</translation>
<translation id="2774256287122201187">Folytathatja a böngészést. Ha továbblép az oldalra, akkor ez a figyelmeztetés a következő öt percben nem fog újra megjelenni.</translation>
<translation id="277499241957683684">Hiányzó eszközrekord</translation>
<translation id="2835170189407361413">Űrlap törlése</translation>
-<translation id="2855922900409897335">A(z) <ph name="CREDIT_CARD"/> kártya igazolása</translation>
+<translation id="2855922900409897335">A(z) <ph name="CREDIT_CARD" /> kártya igazolása</translation>
+<translation id="2915500479781995473">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa lejárt. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását. Számítógépének órája jelenleg <ph name="CURRENT_TIME" /> időre van állítva. Ez helyesnek tűnik? Ha nem, állítsa be megfelelően a rendszer óráját, majd frissítse az oldalt.</translation>
+<translation id="2922350208395188000">A szerver tanúsítványát nem sikerült leellenőrizni.</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="2958431318199492670">A hálózati konfiguráció nem felel meg az ONC szabványnak. A konfiguráció egyes részeit nem lehet importálni.</translation>
<translation id="2972581237482394796">&amp;Újra</translation>
-<translation id="3010559122411665027">&quot;<ph name="ENTRY_INDEX"/>.&quot; listabejegyzés: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">"<ph name="ENTRY_INDEX" />." listabejegyzés: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Nem megfelelő irányelvtípus</translation>
<translation id="3105172416063519923">Tartalomazonosító:</translation>
<translation id="3145945101586104090">Nem sikerült dekódolni a választ</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Sziget</translation>
<translation id="3219579145727097045">Adja meg a lejárati dátumot, és a kártya elején szereplő négyjegyű CVC-kódot</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="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="3228969707346345236">A fordítás nem sikerült, mert az oldal már ezen a nyelven van: <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Átrendezés visszavonása</translation>
+<translation id="3286538390144397061">Újraindítás most</translation>
<translation id="333371639341676808">Ez az oldal ne nyisson meg további párbeszédablakokat.</translation>
-<translation id="3369366829301677151">Aktualizálja és igazolja a következő kártyáját: <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">beállítások</translation>
+<translation id="3369192424181595722">Órahiba</translation>
+<translation id="3369366829301677151">Aktualizálja és igazolja a következő kártyáját: <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Deaktiválva</translation>
<translation id="3377188786107721145">Irányelv-előfeldolgozási hiba</translation>
<translation id="3380365263193509176">Ismeretlen hiba</translation>
<translation id="3380864720620200369">Ügyfél-azonosító:</translation>
<translation id="3427342743765426898">&amp;Szerkesztés újra</translation>
+<translation id="3435896845095436175">Engedélyezés</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Lekérési intervallum:</translation>
+<translation id="3462200631372590220">Speciális beállítások elrejtése</translation>
+<translation id="3528171143076753409">A szervezet tanúsítványa nem megbízható.</translation>
<translation id="3542684924769048008">Jelszó használata a következőre:</translation>
<translation id="3583757800736429874">&amp;Áthelyezés újra</translation>
<translation id="3623476034248543066">Érték megjelenítése</translation>
+<translation id="3648607100222897006">Ezek a kísérleti funkciók bármikor megváltozhatnak, elromolhatnak vagy eltűnhetnek. Nem vállalunk semmilyen garanciát az ezen kísérleti funkciók bekapcsolásából származó eseményekért; továbbá böngészője váratlanul összeomolhat. A viccet félretéve, a böngészője törölheti az összes adatot, valamint különböző módokon veszélyeztetheti biztonságát és adatvédelmét. Ha bármilyen kísérleti funkciót engedélyez, az a böngésző minden felhasználója számára engedélyezve lesz. Kérjük, óvatosan lépjen tovább.</translation>
<translation id="3650584904733503804">Sikeres érvényesítés</translation>
<translation id="370665806235115550">Betöltés…</translation>
<translation id="3712624925041724820">Az engedélyek elfogytak</translation>
<translation id="3739623965217189342">Átmásolt link</translation>
<translation id="375403751935624634">A fordítás a szerver hibája miatt nem sikerült.</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>
<translation id="3885155851504623709">Körzet</translation>
<translation id="3934680773876859118">PDF dokumentum betöltése sikertelen</translation>
<translation id="3963721102035795474">Olvasási mód</translation>
<translation id="4030383055268325496">&amp;Hozzáadás visszavonása</translation>
-<translation id="4058922952496707368">&quot;<ph name="SUBKEY"/>&quot; kulcs: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">FIGYELMEZTETÉS</translation>
+<translation id="4058922952496707368">"<ph name="SUBKEY" />" kulcs: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">A proxykonfiguráció a .pac típusú szkript URL-cím, nem pedig a fix proxyszerverek használatára van beállítva.</translation>
<translation id="409504436206021213">Ne töltse újra</translation>
<translation id="4103249731201008433">Az eszköz sorozatszáma érvénytelen</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Rossz aláírás</translation>
<translation id="4269787794583293679">(Nincs felhasználónév)</translation>
<translation id="4300246636397505754">Szülői javaslatok</translation>
-<translation id="4372948949327679948">Várt <ph name="VALUE_TYPE"/> érték.</translation>
+<translation id="4325863107915753736">Nem sikerült megtalálni a cikket</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="4394049700291259645">Kikapcsolás</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="443673843213245140">A proxy használata le van tiltva, de kifejezett proxykonfiguráció van megadva.</translation>
-<translation id="4506176782989081258">Érvényesítési hiba: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Érvényesítési hiba: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Eltávolítja a címet a Chrome-ból?</translation>
<translation id="4594403342090139922">&amp;Törlés visszavonása</translation>
<translation id="4607653538520819196">Ez az oldal nem jeleníthető meg az Adatforgalom-csökkentő használatával.</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="4726672564094551039">Házirendek újratöltése</translation>
+<translation id="4728558894243024398">Platform</translation>
+<translation id="4771973620359291008">Ismeretlen hiba történt.</translation>
<translation id="4800132727771399293">Ellenőrizze a lejárati dátumot és a CVC-t, majd próbálja újra</translation>
<translation id="4813512666221746211">Hálózati hiba</translation>
+<translation id="4816492930507672669">Igazítás az oldalmérethez</translation>
<translation id="4850886885716139402">Nézet</translation>
-<translation id="4923417429809017348">Ezt az oldalt lefordították egy ismeretlen nyelvről <ph name="LANGUAGE_LANGUAGE"/> nyelvre</translation>
+<translation id="4923417429809017348">Ezt az oldalt lefordították egy ismeretlen nyelvről <ph name="LANGUAGE_LANGUAGE" /> nyelvre</translation>
<translation id="4926049483395192435">Meg kell határozni.</translation>
<translation id="4968547170521245791">A helyettesítés (proxy) nem hajtható végre</translation>
-<translation id="498957508165411911">Lefordítja <ph name="ORIGINAL_LANGUAGE"/> nyelvről <ph name="TARGET_LANGUAGE"/> nyelvre?</translation>
+<translation id="498957508165411911">Lefordítja <ph name="ORIGINAL_LANGUAGE" /> nyelvről <ph name="TARGET_LANGUAGE" /> nyelvre?</translation>
<translation id="5019198164206649151">A háttértároló állapota nem megfelelő</translation>
<translation id="5031870354684148875">A Google Fordító leírása</translation>
+<translation id="5045550434625856497">Téves jelszó</translation>
+<translation id="5087286274860437796">A szerver tanúsítványa jelenleg nem érvényes.</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="5145883236150621069">Az irányelv válasza hibakódot tartalmaz</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="5179510805599951267">Nem <ph name="ORIGINAL_LANGUAGE" /> nyelven van? Hiba bejelentése</translation>
<translation id="5190835502935405962">Könyvjelzősáv</translation>
+<translation id="5199729219167945352">Kísérletek</translation>
+<translation id="5251803541071282808">Felhő</translation>
<translation id="5295309862264981122">Navigálás megerősítése</translation>
<translation id="5299298092464848405">Irányelv-előfeldolgozási hiba</translation>
+<translation id="5316812925700871227">Forgatás balra</translation>
<translation id="5317780077021120954">Mentés</translation>
<translation id="536296301121032821">Az irányelv-beállítások tárolása sikertelen</translation>
-<translation id="5439770059721715174">Sémaérvényesítési hiba a következőnél: „<ph name="ERROR_PATH"/>”: <ph name="ERROR"/></translation>
+<translation id="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="5439770059721715174">Sémaérvényesítési hiba a következőnél: „<ph name="ERROR_PATH" />”: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Hibás az irányelv időbélyege</translation>
<translation id="5470861586879999274">&amp;Szerkesztés újra</translation>
<translation id="5509780412636533143">Kezelt könyvjelzők</translation>
<translation id="5523118979700054094">Az irányelv neve</translation>
<translation id="552553974213252141">Megfelelően kinyerte a szöveget?</translation>
<translation id="5540224163453853">A kért cikk nem található.</translation>
+<translation id="5556459405103347317">Újratöltés</translation>
<translation id="5565735124758917034">Aktív</translation>
<translation id="560412284261940334">A kezelés nem támogatott</translation>
<translation id="5629630648637658800">Az irányelv-beállítások betöltése sikertelen</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Jelenlegi felhasználó</translation>
<translation id="5813119285467412249">&amp;Hozzáadás újra</translation>
<translation id="5872918882028971132">Szülői javaslatok</translation>
-<translation id="587701087903783706">A mobilbarát nézet bezárása</translation>
<translation id="59107663811261420">A Google Payments ennél a kereskedőnél nem támogatja az ilyen típusú kártyákat. Kérjük, válasszon másik kártyát.</translation>
+<translation id="5975083100439434680">Kicsinyítés</translation>
<translation id="5989320800837274978">Sem fix proxyszerver, sem pedig .pac típusú szkript URL-címe nincs megadva.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Bezárás</translation>
+<translation id="6060685159320643512">Óvatosan, ezek a kísérletek haraphatnak</translation>
+<translation id="6151417162996330722">A szervertanúsítvány érvényességi ideje túl hosszú.</translation>
<translation id="6154808779448689242">A visszaadott irányelvtoken nem egyezik az aktuális tokennel</translation>
<translation id="6165508094623778733">További információ</translation>
<translation id="6259156558325130047">&amp;Átrendezés újra</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> könyvjelzők</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> könyvjelzők</translation>
<translation id="6282194474023008486">Irányítószám</translation>
<translation id="6337534724793800597">Házirendek szűrése név szerint</translation>
+<translation id="6387478394221739770">Érdekli néhány remek új Chrome-funkció? Próbálja ki a Béta csatornánkat a chrome.com/beta webhelyen.</translation>
+<translation id="6426993025560594914">Az összes kísérlet elérhető az Ön operációs rendszerén!</translation>
<translation id="6445051938772793705">Ország</translation>
<translation id="6458467102616083041">A rendszer figyelmen kívül hagyja, mivel az alapértelmezett keresést házirend tiltja le.</translation>
<translation id="647261751007945333">Eszközházirendek</translation>
<translation id="6512448926095770873">Az oldal elhagyása</translation>
<translation id="6529602333819889595">&amp;Törlés újra</translation>
<translation id="6550675742724504774">Beállítások</translation>
-<translation id="6597614308054261376">A következő webhelyet próbálja elérni: <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Az Adatforgalom-csökkentő jelenleg nem tudja megjeleníteni ezt az oldalt.</translation>
-<translation id="6628463337424475685">Keresés: <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">A következő webhelyet próbálja elérni: <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Az Adatforgalom-csökkentő jelenleg nem tudja megjeleníteni ezt az oldalt.</translation>
+<translation id="6628463337424475685">Keresés: <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Ez a házirend már elavult.</translation>
<translation id="6646897916597483132">Adja meg a kártya elején szereplő négyjegyű CVC-kódot</translation>
+<translation id="674375294223700098">Ismeretlen szervertanúsítvány-hiba.</translation>
<translation id="6753269504797312559">Házirend értéke</translation>
<translation id="6831043979455480757">Fordítás</translation>
<translation id="6839929833149231406">Körzet</translation>
<translation id="6874604403660855544">&amp;Hozzáadás újra</translation>
<translation id="6891596781022320156">Ezt a házirendszintet a rendszer nem támogatja.</translation>
<translation id="6915804003454593391">Felhasználó:</translation>
+<translation id="6957887021205513506">A szerver tanúsítványa hamisítványnak tűnik.</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6965978654500191972">Készülék</translation>
<translation id="6970216967273061347">Kerület</translation>
<translation id="6973656660372572881">Mindkét fix proxyszerver és egy .Pac típusú szkript URL-címe meg van adva.</translation>
<translation id="6980028882292583085">JavaScript-figyelmeztetés</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Ön megpróbálta elérni a(z) <ph name="DOMAIN" /> domaint, de a szerver olyan tanúsítványt küldött, amelynek érvényességi ideje túl hosszú ahhoz, hogy megbízható legyen.</translation>
<translation id="7087282848513945231">Megye</translation>
-<translation id="7108649287766967076">A(z) <ph name="TARGET_LANGUAGE"/> nyelvre fordítás sikertelen volt.</translation>
+<translation id="7108649287766967076">A(z) <ph name="TARGET_LANGUAGE" /> nyelvre fordítás sikertelen volt.</translation>
<translation id="7139724024395191329">Emírség</translation>
+<translation id="7179921470347911571">Újraindítás most</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="7186367841673660872">Ezt az oldalt<ph name="ORIGINAL_LANGUAGE" />nyelvről fordítottuk<ph name="LANGUAGE_LANGUAGE" />nyelvre.</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Keresés <ph name="SITE_NAME"/> keresővel a következő kifejezésre: &quot;<ph name="SEARCH_TERMS"/>&quot;</translation>
+<translation id="7208899522964477531">Keresés <ph name="SITE_NAME" /> keresővel a következő kifejezésre: "<ph name="SEARCH_TERMS" />"</translation>
+<translation id="725866823122871198">Nem hozható létre privát kapcsolat a következővel: <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, mert a számítógép dátum- és időbeállítása helytelen (<ph name="DATE_AND_TIME" />).</translation>
<translation id="7275334191706090484">Kezelt könyvjelzők</translation>
<translation id="7298195798382681320">Ajánlott</translation>
<translation id="7334320624316649418">&amp;Átrendezés újra</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Kötelező</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="7568593326407688803">Az oldal nyelve<ph name="ORIGINAL_LANGUAGE"/>Kívánja lefordítani?</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="7568593326407688803">Az oldal nyelve<ph name="ORIGINAL_LANGUAGE" />Kívánja lefordítani?</translation>
<translation id="7569952961197462199">Eltávolítja a hitelkártyát a Chrome-ból?</translation>
-<translation id="7600965453749440009">Soha ne fordítsa le a(z) <ph name="LANGUAGE"/> nyelvű szöveget</translation>
-<translation id="7610193165460212391">Az érték kívül esik a következő tartományon: <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">A szervertanúsítvány sérti a névre vonatkozó megkötéseket.</translation>
+<translation id="7600965453749440009">Soha ne fordítsa le a(z) <ph name="LANGUAGE" /> nyelvű szöveget</translation>
+<translation id="7610193165460212391">Az érték kívül esik a következő tartományon: <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Érdekli néhány remek új Chrome-funkció? Próbálja ki a fejlesztői csatornánkat a chrome.com/dev webhelyen.</translation>
<translation id="7752995774971033316">Nem kezelt</translation>
+<translation id="7761701407923456692">A szerver tanúsítványa nem egyezik az URL-lel</translation>
<translation id="777702478322588152">Prefektúra</translation>
<translation id="7791543448312431591">Hozzáadás</translation>
<translation id="7805768142964895445">Állapot</translation>
<translation id="7813600968533626083">Eltávolítja a javaslatot a Chrome-ból?</translation>
<translation id="7887683347370398519">Ellenőrizze a CVC-t, majd próbálja újra</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">A szerver tanúsítványa még nem érvényes.</translation>
<translation id="7956713633345437162">Mobil könyvjelzők</translation>
<translation id="7961015016161918242">Soha</translation>
<translation id="7977590112176369853">&lt;lekérdezés megadása&gt;</translation>
-<translation id="7983301409776629893">A(z) <ph name="ORIGINAL_LANGUAGE"/> nyelvű szövegeket mindig fordítsa <ph name="TARGET_LANGUAGE"/> nyelvre</translation>
+<translation id="7983301409776629893">A(z) <ph name="ORIGINAL_LANGUAGE" /> nyelvű szövegeket mindig fordítsa <ph name="TARGET_LANGUAGE" /> nyelvre</translation>
<translation id="7988324688042446538">Asztali könyvjelzők</translation>
<translation id="7995512525968007366">Nincs megadva</translation>
-<translation id="8034522405403831421">Ez az oldal <ph name="SOURCE_LANGUAGE"/> nyelven van. Lefordítja <ph name="TARGET_LANGUAGE"/> nyelvre?</translation>
+<translation id="8003882219468422867">Vállalati felülbírálás</translation>
+<translation id="8034522405403831421">Ez az oldal <ph name="SOURCE_LANGUAGE" /> nyelven van. Lefordítja <ph name="TARGET_LANGUAGE" /> nyelvre?</translation>
<translation id="8088680233425245692">Nem sikerült megtekinteni a cikket.</translation>
<translation id="8091372947890762290">Az aktiválás függőben van a szerveren</translation>
<translation id="8194797478851900357">&amp;Áthelyezés visszavonása</translation>
-<translation id="8201077131113104583">A(z) „<ph name="EXTENSION_ID"/>” azonosítójú bővítmény frissítési URL-je érvénytelen.</translation>
+<translation id="8201077131113104583">A(z) „<ph name="EXTENSION_ID" />” azonosítójú bővítmény frissítési URL-je érvénytelen.</translation>
<translation id="8208216423136871611">Ne mentse</translation>
<translation id="8218327578424803826">Hozzárendelt helyszín:</translation>
<translation id="8249320324621329438">Utolsó lekérés:</translation>
+<translation id="8294431847097064396">Forrás</translation>
<translation id="8308427013383895095">A fordítás a hálózati kapcsolat problémája miatt nem sikerült.</translation>
<translation id="8311778656528046050">Biztos, hogy újra szeretné tölteni ezt az oldalt?</translation>
<translation id="8349305172487531364">Könyvjelzősáv</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">A következőre érvényes</translation>
<translation id="8530504477309582336">A Google Payments nem támogatja az ilyen típusú kártyákat. Kérjük, válasszon egy másikat.</translation>
<translation id="8553075262323480129">A fordítás nem sikerült, mivel az oldal nyelvét nem lehet megállapítani.</translation>
-<translation id="8571890674111243710">Oldal fordítása erre a nyelvre: <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Nem hozható létre privát kapcsolat a következővel: <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, mert az eszköz dátum- és időbeállítása helytelen (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="8571890674111243710">Oldal fordítása erre a nyelvre: <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Minden visszaállítása az alapértékre</translation>
<translation id="8713130696108419660">Helytelen első aláírás</translation>
<translation id="8725066075913043281">Újrapróbálás</translation>
+<translation id="8738058698779197622">Biztonságos kapcsolat létrehozásához az órát pontosan be kell állítani. Ez azért szükséges, mert a webhelyek által az azonosításukra használt tanúsítványok csak adott ideig érvényesek. Mivel az eszköz órája nem pontos, a Chromium nem tudja ellenőrizni ezeket a tanúsítványokat.</translation>
<translation id="8790007591277257123">&amp;Törlés újra</translation>
<translation id="8804164990146287819">Adatvédelmi irányelvek</translation>
+<translation id="8820817407110198400">Könyvjelzők</translation>
<translation id="8824019021993735287">A Chrome ez alkalommal nem tudta azonosítani kártyáját. Próbálja újra később.</translation>
<translation id="8834246243508017242">Az Ismerősöket felhasználó Automatikus kitöltés engedélyezése…</translation>
<translation id="883848425547221593">Egyéb könyvjelzők</translation>
+<translation id="884923133447025588">Nem található visszavonási mechanizmus.</translation>
<translation id="8866481888320382733">Irányelv-beállítások előfeldolgozási hibája</translation>
<translation id="8876793034577346603">A hálózati konfiguráció előfeldolgozása sikertelen.</translation>
<translation id="8891727572606052622">Érvénytelen proxymód.</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/> futtatása a következő paranccsal: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Sajnos ez a kísérlet nem érhető el az Ön operációs rendszerén.</translation>
+<translation id="8903921497873541725">Nagyítás</translation>
+<translation id="8932102934695377596">Késik az órája</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" /> futtatása a következő paranccsal: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">A szerver tanúsítványa lejárt.</translation>
<translation id="8988760548304185580">Adja meg a lejárati dátumot, és a kártya hátoldalán szereplő háromjegyű CVC-kódot</translation>
-<translation id="9020542370529661692">Az oldalt lefordítottuk <ph name="TARGET_LANGUAGE"/> nyelvre.</translation>
+<translation id="901974403500617787">Rendszerszinten érvényes jelölőket csak a tulajdonos (<ph name="OWNER_EMAIL" />) állíthat be.</translation>
+<translation id="9020542370529661692">Az oldalt lefordítottuk <ph name="TARGET_LANGUAGE" /> nyelvre.</translation>
+<translation id="9049981332609050619">Megpróbálta elérni a(z) <ph name="DOMAIN" /> webhelyet, de a szerver érvénytelen tanúsítványt mutatott be.</translation>
<translation id="9125941078353557812">Adja meg a kártya hátoldalán szereplő háromjegyű CVC-kódot</translation>
<translation id="9137013805542155359">Eredeti megjelenítése</translation>
<translation id="9148507642005240123">&amp;Szerkesztés visszavonása</translation>
<translation id="9154176715500758432">Maradok ezen az oldalon</translation>
<translation id="9170848237812810038">&amp;Visszavonás</translation>
+<translation id="917450738466192189">A szerver tanúsítványa érvénytelen.</translation>
+<translation id="9187827965378254003">Jaj, úgy tűnik, pillanatnyilag nincs elérhető kísérlet.</translation>
<translation id="9207861905230894330">A cikk hozzáadása sikertelen.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ŰRLAP TÖRLÉSE</translation>
+<translation id="988159990683914416">Fejlesztői változat</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_id.xtb b/chromium/components/strings/components_strings_id.xtb
index 87f1979eba7..41ea48788cf 100644
--- a/chromium/components/strings/components_strings_id.xtb
+++ b/chromium/components/strings/components_strings_id.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="id">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="id">
+<translation id="1032854598605920125">Putar searah jarum jam</translation>
<translation id="1055184225775184556">&amp;Urungkan Penambahan</translation>
<translation id="106701514854093668">Bookmark Desktop</translation>
-<translation id="1103523840287552314">Selalu terjemahkan <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Paskan dengan lebar</translation>
+<translation id="1103523840287552314">Selalu terjemahkan <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Urungkan pengaturan ulang</translation>
<translation id="111844081046043029">Yakin ingin meninggalkan laman ini?</translation>
<translation id="112840717907525620">Cache kebijakan Oke</translation>
<translation id="1132774398110320017">Setelan IsiOtomatis Chrome...</translation>
-<translation id="1152921474424827756">Akses <ph name="BEGIN_LINK"/>salinan yang disimpan dalam cache<ph name="END_LINK"/> dari <ph name="URL"/></translation>
+<translation id="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="1152921474424827756">Akses <ph name="BEGIN_LINK" />salinan yang disimpan dalam cache<ph name="END_LINK" /> dari <ph name="URL" /></translation>
+<translation id="121201262018556460">Anda bermaksud membuka <ph name="DOMAIN" />, namun server menyajikan sertifikat yang berisi kunci yang lemah. Penyerang mungkin telah merusak kunci pribadi, dan server mungkin bukan yang diharapkan (Anda mungkin sedang berkomunikasi dengan penyerang).</translation>
<translation id="1227224963052638717">Kebijakan tidak dikenal.</translation>
<translation id="1227633850867390598">Sembunyikan nilai</translation>
<translation id="1228893227497259893">Pengidentifikasi entitas salah</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Domain pendaftaran:</translation>
<translation id="1344588688991793829">Setelan IsiOtomatis Chromium...</translation>
<translation id="1426410128494586442">Ya</translation>
+<translation id="1430915738399379752">Cetak</translation>
<translation id="1455235771979731432">Terjadi masalah saat memverifikasi kartu. Periksa sambungan internet Anda dan coba lagi.</translation>
<translation id="1491151370853475546">Muat Ulang Laman Ini</translation>
<translation id="1549470594296187301">JavaScript harus diaktifkan untuk menggunakan fitur ini.</translation>
-<translation id="1639239467298939599">Memuat</translation>
<translation id="1640180200866533862">Kebijakan pengguna</translation>
<translation id="1644184664548287040">Konfigurasi cadangan tidak valid dan tidak dapat diimpor.</translation>
-<translation id="1693754753824026215">Laman di <ph name="SITE"/> menyatakan:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; masa berlaku sertifikat keamanannya telah berakhir kemarin. Hal ini mungkin disebabkan oleh kesalahan konfigurasi, atau ada penyerang yang memintas sambungan internet Anda. Jam komputer Anda saat ini diatur ke <ph name="CURRENT_DATE" />. Apakah terlihat sesuai? Jika tidak, Anda harus membenarkan jam sistem dan menyegarkan laman ini.}other{Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; masa berlaku sertifikat keamanannya telah berakhir # hari yang lalu. Hal ini mungkin disebabkan oleh kesalahan konfigurasi, atau ada penyerang yang memintas sambungan internet Anda. Jam komputer Anda saat ini diatur ke <ph name="CURRENT_DATE" />. Apakah terlihat sesuai? Jika tidak, Anda harus membenarkan jam sistem dan menyegarkan laman ini.}}</translation>
+<translation id="168841957122794586">Sertifikat server berisi kunci kriptografis yang lemah.</translation>
+<translation id="1693754753824026215">Laman di <ph name="SITE" /> menyatakan:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak dipercaya oleh sistem operasi perangkat Anda. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
<translation id="1821930232296380041">Permintaan atau parameter permintaan tidak valid</translation>
-<translation id="1853748787962613237">Gagal menampilkan artikel.</translation>
<translation id="1871208020102129563">Proxy disetel untuk menggunakan server proxy tetap, bukan URL skrip .pac.</translation>
-<translation id="1875753206475436906">jenis heuristik: <ph name="HEURISTIC_TYPE"/>
- jenis server: <ph name="SERVER_TYPE"/>
- tanda tangan bidang: <ph name="FIELD_SIGNATURE"/>
- tanda tangan formulir: <ph name="FORM_SIGNATURE"/>
- id eksperimen: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Buka <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Bookmark <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Buka <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Bookmark <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Kesalahan serialisasi</translation>
+<translation id="1974060860693918893">Lanjutan</translation>
<translation id="2025186561304664664">Proxy disetel ke konfigurasi otomatis.</translation>
<translation id="2025623846716345241">Konfirmasi Pemuatan Ulang</translation>
-<translation id="2030481566774242610">Mungkin maksud Anda <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Mungkin maksud Anda <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Kode pos</translation>
<translation id="20817612488360358">Setelan proxy sistem disetel untuk digunakan namun konfigurasi proxy eksplisit juga ditentukan.</translation>
<translation id="2094505752054353250">Ketidakcocokan domain</translation>
<translation id="2096368010154057602">Departemen</translation>
<translation id="2113977810652731515">Kartu</translation>
-<translation id="2114841414352855701">Diabaikan karena diganti dengan <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Diabaikan karena diganti dengan <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Bookmark Seluler</translation>
+<translation id="2171101176734966184">Anda berusaha menjangkau <ph name="DOMAIN" />, tetapi server menyajikan sertifikat yang ditandatangani menggunakan algoritme tanda tangan yang lemah. Artinya kredensial keamanan yang disajikan server mungkin telah dipalsukan, dan server tersebut mungkin bukan yang diharapkan (Anda mungkin sedang berkomunikasi dengan penyerang).</translation>
<translation id="2181821976797666341">Kebijakan</translation>
<translation id="2212735316055980242">Kebijakan tidak ditemukan</translation>
<translation id="2213606439339815911">Mengambil entri...</translation>
<translation id="225207911366869382">Nilai ini sudah usang untuk kebijakan ini.</translation>
<translation id="2262243747453050782">Kesalahan HTTP</translation>
-<translation id="2270192940992995399">Gagal menemukan artikel.</translation>
-<translation id="2328300916057834155">Mengabaikan bookmark tidak valid di indeks <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Eksperimen Tidak Tersedia</translation>
+<translation id="229702904922032456">Masa berlaku sertifikat akar atau menengah telah berakhir.</translation>
+<translation id="2328300916057834155">Mengabaikan bookmark tidak valid di indeks <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Bookmark lain</translation>
<translation id="2359808026110333948">Lanjut</translation>
<translation id="2367567093518048410">Tingkat</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="2396249848217231973">&amp;Urungkan penghapusan</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="2455981314101692989">Laman web ini telah menonaktifkan pengisian otomatis untuk formulir ini.</translation>
<translation id="2479410451996844060">URL penelusuran tidak valid.</translation>
+<translation id="2491120439723279231">Sertifikat server mengandung kesalahan.</translation>
<translation id="2495083838625180221">Pengurai JSON</translation>
<translation id="2498091847651709837">Pindai kartu baru</translation>
<translation id="2556876185419854533">&amp;Urungkan Pengeditan</translation>
-<translation id="2581221116934462656">Apakah Anda ingin <ph name="PRODUCT_NAME"/> menawarkan terjemahan laman <ph name="LANGUAGE_NAME"/> dari situs ini saat mengunjunginya nanti?</translation>
+<translation id="2581221116934462656">Apakah Anda ingin <ph name="PRODUCT_NAME" /> menawarkan terjemahan laman <ph name="LANGUAGE_NAME" /> dari situs ini saat mengunjunginya nanti?</translation>
<translation id="2587841377698384444">ID API Direktori:</translation>
<translation id="2597378329261239068">Dokumen ini dilindungi sandi. Masukkan sandi.</translation>
+<translation id="2625385379895617796">Setelan jam terlalu cepat</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2653659639078652383">Kirim</translation>
<translation id="2704283930420550640">Nilai tidak sesuai format.</translation>
<translation id="2721148159707890343">Permintaan berhasil</translation>
+<translation id="2728127805433021124">Sertifikat server ditandai menggunakan algoritme yang lemah.</translation>
<translation id="2774256287122201187">Anda dapat melanjutkannya. Jika Anda melanjutkan ke laman tersebut, peringatan ini tidak akan muncul lagi selama lima menit.</translation>
<translation id="277499241957683684">Catatan perangkat hilang</translation>
<translation id="2835170189407361413">Hapus formulir</translation>
-<translation id="2855922900409897335">Verifikasi <ph name="CREDIT_CARD"/> Anda</translation>
+<translation id="2855922900409897335">Verifikasi <ph name="CREDIT_CARD" /> Anda</translation>
+<translation id="2915500479781995473">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; masa berlaku sertifikat keamanannya telah habis. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda. Saat ini jam komputer Anda disetel ke <ph name="CURRENT_TIME" />. Apakah sudah benar? Jika belum, sebaiknya perbaiki jam sistem kemudian segarkan laman ini.</translation>
+<translation id="2922350208395188000">Sertifikat server tidak dapat diperiksa.</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="2958431318199492670">Konfigurasi jaringan tidak mematuhi standar ONC. Bagian dari konfigurasi mungkin tidak diimpor.</translation>
<translation id="2972581237482394796">&amp;Ulang</translation>
-<translation id="3010559122411665027">Entri daftar &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Entri daftar "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Jenis kebijakan salah</translation>
<translation id="3105172416063519923">ID Aset:</translation>
<translation id="3145945101586104090">Gagal mendekodekan tanggapan</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Pulau</translation>
<translation id="3219579145727097045">Masukkan tanggal masa berlaku habis dan 4 digit CVC di depan kartu Anda</translation>
-<translation id="3228969707346345236">Terjemahan gagal karena laman sudah dalam bahasa <ph name="LANGUAGE"/>.</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="3228969707346345236">Terjemahan gagal karena laman sudah dalam bahasa <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Urungkan Pengaturan Ulang</translation>
+<translation id="3286538390144397061">Mulai Ulang Sekarang</translation>
<translation id="333371639341676808">Cegah dialog lain dari laman ini.</translation>
-<translation id="3369366829301677151">Perbarui dan verifikasi <ph name="CREDIT_CARD"/> Anda</translation>
+<translation id="3340978935015468852">setelan</translation>
+<translation id="3369192424181595722">Kesalahan jam</translation>
+<translation id="3369366829301677151">Perbarui dan verifikasi <ph name="CREDIT_CARD" /> Anda</translation>
<translation id="337363190475750230">Tidak ditetapkan</translation>
<translation id="3377188786107721145">Kesalahan penguraian kebijakan</translation>
<translation id="3380365263193509176">Kesalahan tidak dikenal</translation>
<translation id="3380864720620200369">ID Klien:</translation>
<translation id="3427342743765426898">&amp;Ulangi Pengeditan</translation>
+<translation id="3435896845095436175">Aktifkan</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Interval pengambilan:</translation>
+<translation id="3462200631372590220">Sembunyikan lanjutan</translation>
+<translation id="3528171143076753409">Sertifikat server tidak dipercaya.</translation>
<translation id="3542684924769048008">Gunakan sandi untuk:</translation>
<translation id="3583757800736429874">&amp;Ulangi Pemindahan</translation>
<translation id="3623476034248543066">Tampilkan nilai</translation>
+<translation id="3648607100222897006">Fitur eksperimental ini bisa berubah, rusak, atau hilang kapan saja. Kami sama sekali tidak menjamin apa yang akan terjadi saat eksperimen ini dinyalakan, siapa tahu browser Anda tiba-tiba hangus terbakar! Becanda! Tapi bisa jadi browser akan menghapus semua data, atau keamanan dan privasi Anda akan disusupi secara tak terduga. Eksperimen yang Anda aktifkan akan diaktifkan untuk semua pengguna browser ini. Lanjutkan dengan hati-hati.</translation>
<translation id="3650584904733503804">Validasi berhasil</translation>
<translation id="370665806235115550">Membuka...</translation>
<translation id="3712624925041724820">Lisensi habis</translation>
<translation id="3739623965217189342">Tautan yang Anda salin</translation>
<translation id="375403751935624634">Terjemahan gagal karena kesalahan server.</translation>
<translation id="385051799172605136">Mundur</translation>
+<translation id="3858027520442213535">Perbarui tanggal dan waktu</translation>
<translation id="3884278016824448484">Pengenal perangkat bertentangan</translation>
<translation id="3885155851504623709">Parish</translation>
<translation id="3934680773876859118">Gagal memuat dokumen PDF</translation>
<translation id="3963721102035795474">Mode Pembaca</translation>
<translation id="4030383055268325496">&amp;Urungkan penambahan</translation>
-<translation id="4058922952496707368">Kunci &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">PERINGATAN</translation>
+<translation id="4058922952496707368">Kunci "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Konfigurasi proxy disetel untuk menggunakan URL skrip .pac, bukan server proxy yang tetap.</translation>
<translation id="409504436206021213">Jangan Muat Ulang</translation>
<translation id="4103249731201008433">Nomor seri perangkat tidak valid</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Tanda tangan salah</translation>
<translation id="4269787794583293679">(Tidak ada nama pengguna)</translation>
<translation id="4300246636397505754">Saran induk</translation>
-<translation id="4372948949327679948">Nilai <ph name="VALUE_TYPE"/> yang diharapkan.</translation>
+<translation id="4325863107915753736">Gagal menemukan artikel</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="4394049700291259645">Nonaktifkan</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="443673843213245140">Penggunaan proxy dinonaktifkan tetapi konfigurasi proxy yang eksplisit ditentukan.</translation>
-<translation id="4506176782989081258">Kesalahan validasi: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Kesalahan validasi: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Hapus alamat dari Chrome?</translation>
<translation id="4594403342090139922">&amp;Urungkan Penghapusan</translation>
<translation id="4607653538520819196">Laman ini tidak dapat diberi proxy oleh Penghemat Data.</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="4726672564094551039">Muat ulang kebijakan</translation>
+<translation id="4728558894243024398">Platform</translation>
+<translation id="4771973620359291008">Terjadi kesalahan yang tidak diketahui.</translation>
<translation id="4800132727771399293">Periksa tanggal masa berlaku habis dan CVC, lalu coba lagi</translation>
<translation id="4813512666221746211">Kesalahan jaringan</translation>
+<translation id="4816492930507672669">Paskan dengan halaman</translation>
<translation id="4850886885716139402">Lihat</translation>
-<translation id="4923417429809017348">Laman ini telah diterjemahkan dari bahasa yang tidak diketahui ke bahasa <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Laman ini telah diterjemahkan dari bahasa yang tidak diketahui ke bahasa <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Harus ditentukan.</translation>
<translation id="4968547170521245791">Tidak Dapat Memberi Proxy</translation>
-<translation id="498957508165411911">Terjemahkan dari <ph name="ORIGINAL_LANGUAGE"/> ke <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Terjemahkan dari <ph name="ORIGINAL_LANGUAGE" /> ke <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Penyimpanan cadangan dalam kondisi buruk</translation>
<translation id="5031870354684148875">Tentang Google Terjemahan</translation>
+<translation id="5045550434625856497">Sandi salah</translation>
+<translation id="5087286274860437796">Sertifikat server saat ini tidak valid.</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="5145883236150621069">Ada kode kesalahan dalam tanggapan kebijakan</translation>
<translation id="5172758083709347301">Mesin</translation>
-<translation id="5179510805599951267">Bukan <ph name="ORIGINAL_LANGUAGE"/>? Laporkan kesalahan deteksi ini</translation>
+<translation id="5179510805599951267">Bukan <ph name="ORIGINAL_LANGUAGE" />? Laporkan kesalahan deteksi ini</translation>
<translation id="5190835502935405962">Bilah Bookmark</translation>
+<translation id="5199729219167945352">Eksperimen</translation>
+<translation id="5251803541071282808">Awan</translation>
<translation id="5295309862264981122">Konfirmasikan Navigasi</translation>
<translation id="5299298092464848405">Kebijakan kesalahan penguraian</translation>
+<translation id="5316812925700871227">Putar berlawanan arah jarum jam</translation>
<translation id="5317780077021120954">Simpan</translation>
<translation id="536296301121032821">Gagal menyimpan setelan kebijakan</translation>
-<translation id="5439770059721715174">Kesalahan validasi skema di &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Kesalahan validasi skema di "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Stempel waktu kebijakan salah</translation>
<translation id="5470861586879999274">&amp;Ulangi pengeditan</translation>
<translation id="5509780412636533143">Mengelola bookmark</translation>
<translation id="5523118979700054094">Nama kebijakan</translation>
<translation id="552553974213252141">Apakah teks diekstrak dengan benar?</translation>
<translation id="5540224163453853">Tidak dapat menemukan artikel yang diminta.</translation>
+<translation id="5556459405103347317">Muat ulang</translation>
<translation id="5565735124758917034">Aktif</translation>
<translation id="560412284261940334">Pengelolaan tidak didukung</translation>
<translation id="5629630648637658800">Gagal memuat setelan kebijakan</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Pengguna saat ini</translation>
<translation id="5813119285467412249">&amp;Ulangi Penambahan</translation>
<translation id="5872918882028971132">Saran Induk</translation>
-<translation id="587701087903783706">Tutup tampilan mobile-friendly</translation>
<translation id="59107663811261420">Kartu jenis ini tidak didukung oleh Google Payments untuk pedagang ini. Pilih kartu lain.</translation>
+<translation id="5975083100439434680">Perkecil</translation>
<translation id="5989320800837274978">Baik proxy server tetap ataupun URL skrip .pac tidak ditentukan.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Tutup</translation>
+<translation id="6060685159320643512">Hati-hati, eksperimen ini dapat menimbulkan masalah</translation>
+<translation id="6151417162996330722">Sertifikat server memiliki masa berlaku yang terlalu panjang.</translation>
<translation id="6154808779448689242">Token kebijakan yang dikembalikan tidak cocok dengan token saat ini</translation>
<translation id="6165508094623778733">Pelajari lebih lanjut</translation>
<translation id="6259156558325130047">&amp;Ulangi Pengaturan Ulang</translation>
-<translation id="6263376278284652872">Bookmark <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Bookmark <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Kode pos</translation>
<translation id="6337534724793800597">Filter kebijakan menurut nama</translation>
+<translation id="6387478394221739770">Tertarik dengan fitur Chrome baru yang keren? Coba saluran beta kami di chrome.com/beta.</translation>
+<translation id="6426993025560594914">Semua eksperimen tersedia di platform Anda!</translation>
<translation id="6445051938772793705">Negara</translation>
<translation id="6458467102616083041">Diabaikan karena penelusuran default dinonaktifkan oleh kebijakan.</translation>
<translation id="647261751007945333">Kebijakan perangkat</translation>
<translation id="6512448926095770873">Keluar dari Laman</translation>
<translation id="6529602333819889595">&amp;Ulangi Penghapusan</translation>
<translation id="6550675742724504774">Opsi</translation>
-<translation id="6597614308054261376">Anda mencoba menjangkau <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Saat ini, laman ini tidak dapat diberi proxy oleh Penghemat Data.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Penelusuran</translation>
+<translation id="6597614308054261376">Anda mencoba menjangkau <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Saat ini, laman ini tidak dapat diberi proxy oleh Penghemat Data.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Penelusuran</translation>
<translation id="6644283850729428850">Kebijakan ini telah usang.</translation>
<translation id="6646897916597483132">Masukkan 4 digit CVC di depan kartu Anda</translation>
+<translation id="674375294223700098">Kesalahan sertifikat server tidak dikenal.</translation>
<translation id="6753269504797312559">Nilai kebijakan</translation>
<translation id="6831043979455480757">Terjemahkan</translation>
<translation id="6839929833149231406">Area</translation>
<translation id="6874604403660855544">&amp;Ulangi penambahan</translation>
<translation id="6891596781022320156">Tingkat kebijakan tidak didukung.</translation>
<translation id="6915804003454593391">Pengguna:</translation>
+<translation id="6957887021205513506">Sertifikat server tampaknya palsu.</translation>
<translation id="6965382102122355670">Oke</translation>
<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="6980028882292583085">Lansiran JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Anda berusaha menjangkau <ph name="DOMAIN" />, namun server memberikan sertifikat yang masa berlakunya terlalu lama untuk dapat dipercaya.</translation>
<translation id="7087282848513945231">County</translation>
-<translation id="7108649287766967076">Penerjemahan ke <ph name="TARGET_LANGUAGE"/> gagal.</translation>
+<translation id="7108649287766967076">Penerjemahan ke <ph name="TARGET_LANGUAGE" /> gagal.</translation>
<translation id="7139724024395191329">Emirate</translation>
+<translation id="7179921470347911571">Luncurkan Ulang Sekarang</translation>
<translation id="7180611975245234373">Segarkan</translation>
<translation id="7182878459783632708">Tidak ada kebijakan yang disetel</translation>
-<translation id="7186367841673660872">Laman ini telah diterjemahkan dari<ph name="ORIGINAL_LANGUAGE"/>ke<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="7186367841673660872">Laman ini telah diterjemahkan dari<ph name="ORIGINAL_LANGUAGE" />ke<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Telusuri <ph name="SEARCH_TERMS"/> dengan <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Telusuri <ph name="SEARCH_TERMS" /> dengan <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">Sambungan pribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat dibuat karena tanggal dan waktu (<ph name="DATE_AND_TIME" />) komputer Anda tidak benar.</translation>
<translation id="7275334191706090484">Bookmark yang Terkelola</translation>
<translation id="7298195798382681320">Direkomendasikan</translation>
<translation id="7334320624316649418">&amp;Ulangi pengaturan ulang</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">Javascript</translation>
<translation id="7537536606612762813">Wajib</translation>
<translation id="7542995811387359312">Pengisian kartu kredit otomatis dinonaktifkan karena formulir ini tidak menggunakan sambungan aman.</translation>
-<translation id="7568593326407688803">Laman ini dalam bahasa<ph name="ORIGINAL_LANGUAGE"/>Ingin diterjemahkan?</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="7568593326407688803">Laman ini dalam bahasa<ph name="ORIGINAL_LANGUAGE" />Ingin diterjemahkan?</translation>
<translation id="7569952961197462199">Hapus kartu kredit dari Chrome?</translation>
-<translation id="7600965453749440009">Jangan pernah terjemahkan bahasa <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Nilai di luar jangkauan <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Sertifikat server melanggar batasan nama.</translation>
+<translation id="7600965453749440009">Jangan pernah terjemahkan bahasa <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Nilai di luar jangkauan <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Tertarik dengan fitur Chrome baru yang keren? Coba saluran dev kami di chrome.com/dev.</translation>
<translation id="7752995774971033316">Tidak terkelola</translation>
+<translation id="7761701407923456692">Sertifikat server tidak cocok dengan URL.</translation>
<translation id="777702478322588152">Prefektur</translation>
<translation id="7791543448312431591">Tambahkan</translation>
<translation id="7805768142964895445">Status</translation>
<translation id="7813600968533626083">Hapus sebagai saran dari Chrome?</translation>
<translation id="7887683347370398519">Periksa CVC dan coba lagi</translation>
<translation id="7935318582918952113">Penyaring DOM</translation>
+<translation id="7938958445268990899">Sertifikat server belum valid.</translation>
<translation id="7956713633345437162">Bookmark seluler</translation>
<translation id="7961015016161918242">Tidak pernah</translation>
<translation id="7977590112176369853">&lt;masukkan permintaan&gt;</translation>
-<translation id="7983301409776629893">Selalu terjemahkan <ph name="ORIGINAL_LANGUAGE"/> ke <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Selalu terjemahkan <ph name="ORIGINAL_LANGUAGE" /> ke <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Bookmark desktop</translation>
<translation id="7995512525968007366">Tidak Ditentukan</translation>
-<translation id="8034522405403831421">Laman ini berbahasa <ph name="SOURCE_LANGUAGE"/>. Terjemahkan ke <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Diganti oleh perusahaan</translation>
+<translation id="8034522405403831421">Laman ini berbahasa <ph name="SOURCE_LANGUAGE" />. Terjemahkan ke <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Gagal melihat artikel.</translation>
<translation id="8091372947890762290">Aktivasi ditunda di server</translation>
<translation id="8194797478851900357">&amp;Urungkan Pemindahan</translation>
-<translation id="8201077131113104583">URL pembaruan tidak valid untuk ekstensi dengan ID &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">URL pembaruan tidak valid untuk ekstensi dengan ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Jangan simpan</translation>
<translation id="8218327578424803826">Lokasi yang Ditetapkan:</translation>
<translation id="8249320324621329438">Terakhir diambil:</translation>
+<translation id="8294431847097064396">Sumber</translation>
<translation id="8308427013383895095">Terjemahan gagal karena ada masalah dengan koneksi jaringan.</translation>
<translation id="8311778656528046050">Yakin ingin memuat ulang laman ini?</translation>
<translation id="8349305172487531364">Bilah bookmark</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Berlaku untuk</translation>
<translation id="8530504477309582336">Kartu jenis ini tidak didukung oleh Google Payments. Pilih kartu lain.</translation>
<translation id="8553075262323480129">Terjemahan gagal karena bahasa laman tidak dapat ditentukan.</translation>
-<translation id="8571890674111243710">Menerjemahkan laman ke <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Sambungan pribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat dibuat karena tanggal dan waktu (<ph name="DATE_AND_TIME" />) perangkat tidak benar.</translation>
+<translation id="8571890674111243710">Menerjemahkan laman ke <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Setel ulang semua ke default</translation>
<translation id="8713130696108419660">Tanda tangan awal yang buruk</translation>
<translation id="8725066075913043281">Coba lagi</translation>
+<translation id="8738058698779197622">Untuk membuat sambungan aman, jam perlu disetel dengan benar. Hal ini karena sertifikat yang digunakan situs web untuk mengidentifikasi situs web tersebut hanya valid untuk jangka waktu tertentu. Karena jam perangkat tidak benar, Chromium tidak dapat memverifikasi sertifikat ini.</translation>
<translation id="8790007591277257123">&amp;Ulangi penghapusan</translation>
<translation id="8804164990146287819">Kebijakan Privasi</translation>
+<translation id="8820817407110198400">Bookmark</translation>
<translation id="8824019021993735287">Chrome tidak dapat memverifikasi kartu saat ini. Coba lagi nanti.</translation>
<translation id="8834246243508017242">Aktifkan IsiOtomatis menggunakan Kontak...</translation>
<translation id="883848425547221593">Bookmark Lain</translation>
+<translation id="884923133447025588">Tidak ditemukan mekanisme pembatalan.</translation>
<translation id="8866481888320382733">Kesalahan saat menguraikan setelan kebijakan</translation>
<translation id="8876793034577346603">Konfigurasi jaringan gagal diuraikan.</translation>
<translation id="8891727572606052622">Mode proxy tidak valid.</translation>
-<translation id="8940229512486821554">Jalankan perintah <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Maaf, percobaan ini tidak tersedia di platform Anda.</translation>
+<translation id="8903921497873541725">Perbesar</translation>
+<translation id="8932102934695377596">Setelan waktu Anda terlalu lambat</translation>
+<translation id="8940229512486821554">Jalankan perintah <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Sertifikat server telah kedaluwarsa.</translation>
<translation id="8988760548304185580">Masukkan tanggal masa berlaku habis dan 3 digit CVC di belakang kartu Anda</translation>
-<translation id="9020542370529661692">Laman ini telah diterjemahkan ke <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Tanda yang berlaku bagi sistem secara luas hanya dapat disetel oleh pemilik: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Laman ini telah diterjemahkan ke <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Anda berupaya menjangkau <ph name="DOMAIN" />, tetapi server menyajikan sertifikat yang tidak valid.</translation>
<translation id="9125941078353557812">Masukkan 3 digit CVC di belakang kartu Anda</translation>
<translation id="9137013805542155359">Perlihatkan laman asli</translation>
<translation id="9148507642005240123">&amp;Urungkan pengeditan</translation>
<translation id="9154176715500758432">Tetap di Laman ini</translation>
<translation id="9170848237812810038">&amp;Urung</translation>
+<translation id="917450738466192189">Sertifikat server tidak valid.</translation>
+<translation id="9187827965378254003">Yaah, sekarang tampaknya tidak ada eksperimen yang tersedia.</translation>
<translation id="9207861905230894330">Gagal menambahkan artikel.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">HAPUS FORMULIR</translation>
+<translation id="988159990683914416">Buatan Pengembang</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_it.xtb b/chromium/components/strings/components_strings_it.xtb
index cb3a23e9a70..7249e74ec25 100644
--- a/chromium/components/strings/components_strings_it.xtb
+++ b/chromium/components/strings/components_strings_it.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="it">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="it">
+<translation id="1032854598605920125">Ruota in senso orario</translation>
<translation id="1055184225775184556">&amp;Annulla aggiunta</translation>
<translation id="106701514854093668">Preferiti desktop</translation>
-<translation id="1103523840287552314">Traduci sempre <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Adatta in larghezza</translation>
+<translation id="1103523840287552314">Traduci sempre <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Annulla ridisposizione</translation>
<translation id="111844081046043029">Vuoi uscire dalla pagina?</translation>
<translation id="112840717907525620">Cache dei criteri integra</translation>
<translation id="1132774398110320017">Impostazioni di Compilazione automatica Chrome...</translation>
-<translation id="1152921474424827756">Accedi a una <ph name="BEGIN_LINK"/>copia memorizzata nella cache<ph name="END_LINK"/> di <ph name="URL"/></translation>
+<translation id="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="1152921474424827756">Accedi a una <ph name="BEGIN_LINK" />copia memorizzata nella cache<ph name="END_LINK" /> di <ph name="URL" /></translation>
+<translation id="121201262018556460">Hai tentato di accedere a <ph name="DOMAIN" /> ma il server ha presentato un certificato contenente una chiave debole. Un utente malitenzionato potrebbe avere decifrato la chiave privata e il server potrebbe non essere quello previsto (è possibile che tu stia comunicando con un utente malintenzionato).</translation>
<translation id="1227224963052638717">Norma sconosciuta.</translation>
<translation id="1227633850867390598">Nascondi valore</translation>
<translation id="1228893227497259893">Identificatore entità errato</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Dominio registrazione:</translation>
<translation id="1344588688991793829">Impostazioni di Compilazione automatica Chromium...</translation>
<translation id="1426410128494586442">Sì</translation>
+<translation id="1430915738399379752">Stampa</translation>
<translation id="1455235771979731432">Si è verificato un problema durante la verifica della carta. Controlla la connessione Internet e riprova.</translation>
<translation id="1491151370853475546">Ricarica questa pagina</translation>
<translation id="1549470594296187301">JavaScript deve essere attivato per utilizzare questa funzione.</translation>
-<translation id="1639239467298939599">Caricamento</translation>
<translation id="1640180200866533862">Criteri utente</translation>
<translation id="1644184664548287040">La configurazione di rete non è valida e non può essere importata.</translation>
-<translation id="1693754753824026215">La pagina all'indirizzo <ph name="SITE"/> dice:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza è scaduto ieri. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. L'orologio del computer è attualmente impostato su <ph name="CURRENT_DATE" />. È corretto? Se è sbagliato, dovresti regolare l'orologio e aggiornare la pagina.}other{Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza è scaduto # giorni fa. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. L'orologio del computer è attualmente impostato su <ph name="CURRENT_DATE" />. È corretto? Se è sbagliato, dovresti regolare l'orologio e aggiornare la pagina.}}</translation>
+<translation id="168841957122794586">Il certificato del server contiene una chiave crittografica debole.</translation>
+<translation id="1693754753824026215">La pagina all'indirizzo <ph name="SITE" /> dice:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile dal sistema operativo del dispositivo. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
<translation id="1821930232296380041">Richiesta o parametri della richiesta non validi</translation>
-<translation id="1853748787962613237">Impossibile visualizzare l'articolo.</translation>
<translation id="1871208020102129563">L'impostazione del proxy prevede l'utilizzo di server proxy fissi, non di un URL script .pac.</translation>
-<translation id="1875753206475436906">tipo euristico: <ph name="HEURISTIC_TYPE"/>
- tipo server: <ph name="SERVER_TYPE"/>
- firma campo: <ph name="FIELD_SIGNATURE"/>
- firma modulo: <ph name="FORM_SIGNATURE"/>
- id esperimento: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Vai al link: <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Segnalibri di <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Vai al link: <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Segnalibri di <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Errore di serializzazione</translation>
+<translation id="1974060860693918893">Avanzate</translation>
<translation id="2025186561304664664">È stata impostata la configurazione automatica del proxy.</translation>
<translation id="2025623846716345241">Conferma ricaricamento</translation>
-<translation id="2030481566774242610">Forse cercavi <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Forse cercavi <ph name="LINK" />?</translation>
<translation id="2053553514270667976">ZIP</translation>
<translation id="20817612488360358">Devono essere utilizzate le impostazioni del proxy di sistema ma è stata specificata anche una configurazione proxy esplicita.</translation>
<translation id="2094505752054353250">Dominio non corrispondente</translation>
<translation id="2096368010154057602">Dipartimento</translation>
<translation id="2113977810652731515">Carta</translation>
-<translation id="2114841414352855701">Ignorata perché è stata sostituita da <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Ignorata perché è stata sostituita da <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Preferiti su disp. mobili</translation>
+<translation id="2171101176734966184">Hai tentato di accedere a <ph name="DOMAIN" /> ma il server ha presentato un certificato firmato utilizzando un algoritmo di firma debole. Ciò significa che le credenziali di sicurezza presentate dal server potrebbero essere state falsificate e il server potrebbe non essere quello previsto (è possibile che tu stia comunicando con un utente malintenzionato).</translation>
<translation id="2181821976797666341">Criteri</translation>
<translation id="2212735316055980242">Criterio non trovato</translation>
<translation id="2213606439339815911">Recupero voci...</translation>
<translation id="225207911366869382">Il valore specificato per la norma è obsoleto.</translation>
<translation id="2262243747453050782">Errore HTTP</translation>
-<translation id="2270192940992995399">Impossibile trovare l'articolo.</translation>
-<translation id="2328300916057834155">Preferito non valido dell'indice <ph name="ENTRY_INDEX"/> ignorato</translation>
+<translation id="2282872951544483773">Esperimenti non disponibili</translation>
+<translation id="229702904922032456">Un certificato principale o intermedio è scaduto.</translation>
+<translation id="2328300916057834155">Preferito non valido dell'indice <ph name="ENTRY_INDEX" /> ignorato</translation>
<translation id="2354001756790975382">Altri Preferiti</translation>
<translation id="2359808026110333948">Continua</translation>
<translation id="2367567093518048410">Livello</translation>
+<translation id="2384307209577226199">Valore predefinito aziendale</translation>
+<translation id="2386255080630008482">Il certificato del server è stato revocato.</translation>
<translation id="2392959068659972793">Mostra norme senza valori</translation>
<translation id="2396249848217231973">&amp;Annulla eliminazione</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="2455981314101692989">La pagina web ha disattivato la compilazione automatica per questo modulo.</translation>
<translation id="2479410451996844060">URL ricerca non valido.</translation>
+<translation id="2491120439723279231">Il certificato del server contiene degli errori.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2498091847651709837">Esegui scansione nuova carta</translation>
<translation id="2556876185419854533">&amp;Annulla modifica</translation>
-<translation id="2581221116934462656">Vuoi che <ph name="PRODUCT_NAME"/> ti proponga di tradurre le pagine in <ph name="LANGUAGE_NAME"/> di questo sito la prossima volta?</translation>
+<translation id="2581221116934462656">Vuoi che <ph name="PRODUCT_NAME" /> ti proponga di tradurre le pagine in <ph name="LANGUAGE_NAME" /> di questo sito la prossima volta?</translation>
<translation id="2587841377698384444">ID API directory:</translation>
<translation id="2597378329261239068">Questo documento è protetto da password. Inserisci una password.</translation>
+<translation id="2625385379895617796">L'orologio è avanti</translation>
<translation id="2639739919103226564">Stato:</translation>
+<translation id="2653659639078652383">Invia</translation>
<translation id="2704283930420550640">Il valore non corrisponde al formato.</translation>
<translation id="2721148159707890343">Richiesta riuscita</translation>
+<translation id="2728127805433021124">Il certificato del server è stato firmato utilizzando un algoritmo di firma debole.</translation>
<translation id="2774256287122201187">Puoi continuare. Se rimani nella pagina, questo avviso non verrà più visualizzato per cinque minuti.</translation>
<translation id="277499241957683684">Record del dispositivo mancante</translation>
<translation id="2835170189407361413">Cancella modulo</translation>
-<translation id="2855922900409897335">Verifica la carta <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Verifica la carta <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza è scaduto. Il problema potrebbe essere dovuto a un'errata configurazione o a un malitenzionato che ha intercettato la connessione. L'orologio del tuo computer è attualmente impostato sul giorno <ph name="CURRENT_TIME" />. È corretto? In caso contrario dovresti regolare l'orologio del sistema e aggiornare la pagina.</translation>
+<translation id="2922350208395188000">Il certificato del server non può essere verificato.</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="2958431318199492670">La configurazione di rete non è conforme allo standard ONC. Parti della configurazione potrebbero non essere importate.</translation>
<translation id="2972581237482394796">&amp;Ripeti</translation>
-<translation id="3010559122411665027">Voce &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Voce "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Tipo di criterio errato</translation>
<translation id="3105172416063519923">ID asset:</translation>
<translation id="3145945101586104090">Decodifica della risposta non riuscita</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Isola</translation>
<translation id="3219579145727097045">Inserisci la data di scadenza e il codice CVC di quattro cifre indicato sul retro della carta</translation>
-<translation id="3228969707346345236">La traduzione non è riuscita perché la pagina è già in <ph name="LANGUAGE"/>.</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="3228969707346345236">La traduzione non è riuscita perché la pagina è già in <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Annulla ridisposizione</translation>
+<translation id="3286538390144397061">Riavvia adesso</translation>
<translation id="333371639341676808">Impedisci alla pagina di creare altre finestre di dialogo.</translation>
-<translation id="3369366829301677151">Aggiorna e verifica la tua carta <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">impostazioni</translation>
+<translation id="3369192424181595722">Errore dell'orologio</translation>
+<translation id="3369366829301677151">Aggiorna e verifica la tua carta <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Deprovisioning effettuato</translation>
<translation id="3377188786107721145">Errore di analisi del criterio</translation>
<translation id="3380365263193509176">Errore sconosciuto</translation>
<translation id="3380864720620200369">ID client:</translation>
<translation id="3427342743765426898">&amp;Ripeti modifica</translation>
+<translation id="3435896845095436175">Abilita</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Intervallo recupero:</translation>
+<translation id="3462200631372590220">Nascondi avanzate</translation>
+<translation id="3528171143076753409">Il certificato del server non è affidabile.</translation>
<translation id="3542684924769048008">Utilizza password per:</translation>
<translation id="3583757800736429874">&amp;Ripeti spostamento</translation>
<translation id="3623476034248543066">Mostra valore</translation>
+<translation id="3648607100222897006">Queste funzioni sperimentali potrebbero essere modificate, essere interrotte o scomparire in qualsiasi momento. Non offriamo assolutamente alcuna garanzia su ciò potrebbe accadere se attivi uno di questi esperimenti: il tuo browser potrebbe persino andare in autocombustione! Scherzi a parte, il browser potrebbe eliminare tutti i tuoi dati oppure la tua sicurezza e la tua privacy potrebbero essere compromesse in modi inaspettati. Tutti gli esperimenti che attivi saranno abilitati per tutti gli utenti di questo browser. Procedi con cautela.</translation>
<translation id="3650584904733503804">Convalida riuscita</translation>
<translation id="370665806235115550">Caricamento in corso...</translation>
<translation id="3712624925041724820">Licenze esaurite</translation>
<translation id="3739623965217189342">Link che hai copiato</translation>
<translation id="375403751935624634">La traduzione non è riuscita a causa di un errore del server.</translation>
<translation id="385051799172605136">Indietro</translation>
+<translation id="3858027520442213535">Aggiorna data e ora</translation>
<translation id="3884278016824448484">Identificativo del dispositivo in conflitto</translation>
<translation id="3885155851504623709">Parrocchia</translation>
<translation id="3934680773876859118">Caricamento del documento PDF non riuscito</translation>
<translation id="3963721102035795474">Modalità Reader</translation>
<translation id="4030383055268325496">&amp;Annulla aggiunta</translation>
-<translation id="4058922952496707368">Chiave &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">AVVISO</translation>
+<translation id="4058922952496707368">Chiave "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">L'impostazione della configurazione proxy prevede l'utilizzo di un URL script .pac, non di server proxy fissi.</translation>
<translation id="409504436206021213">Non ricaricare</translation>
<translation id="4103249731201008433">Il numero di serie del dispositivo non è valido</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Firma errata</translation>
<translation id="4269787794583293679">(Nessun nome utente)</translation>
<translation id="4300246636397505754">Suggerimenti per i genitori</translation>
-<translation id="4372948949327679948">È previsto il valore <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Impossibile trovare l'articolo</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="4394049700291259645">Disabilita</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="443673843213245140">L'utilizzo di un proxy è stato disattivato ma è stata specificata una configurazione proxy esplicita.</translation>
-<translation id="4506176782989081258">Errore di convalida. <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Errore di convalida. <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Rimuovere l'indirizzo da Chrome?</translation>
<translation id="4594403342090139922">&amp;Annulla eliminazione</translation>
<translation id="4607653538520819196">Impossibile eseguire il proxy della pagina tramite Risparmio dati.</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="4726672564094551039">Ricarica norme</translation>
+<translation id="4728558894243024398">Piattaforma</translation>
+<translation id="4771973620359291008">Si è verificato un errore sconosciuto.</translation>
<translation id="4800132727771399293">Controlla la data di scadenza e il codice CVC, poi riprova</translation>
<translation id="4813512666221746211">Errore di rete</translation>
+<translation id="4816492930507672669">Adatta alla pagina</translation>
<translation id="4850886885716139402">Visualizza</translation>
-<translation id="4923417429809017348">Questa pagina è stata tradotta da una lingua sconosciuta in <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Questa pagina è stata tradotta da una lingua sconosciuta in <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Deve essere specificato.</translation>
<translation id="4968547170521245791">Impossibile eseguire il proxy</translation>
-<translation id="498957508165411911">Tradurre da <ph name="ORIGINAL_LANGUAGE"/> in <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Tradurre da <ph name="ORIGINAL_LANGUAGE" /> in <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Archivio di backup in stato non valido</translation>
<translation id="5031870354684148875">Informazioni su Google Traduttore</translation>
+<translation id="5045550434625856497">Password non corretta</translation>
+<translation id="5087286274860437796">Il certificato del server non è valido in questa fase.</translation>
<translation id="5089810972385038852">Provincia</translation>
+<translation id="5094747076828555589">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile da Chromium. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
<translation id="5095208057601539847">Provincia</translation>
<translation id="5145883236150621069">Codice di errore presente nella risposta del criterio</translation>
<translation id="5172758083709347301">Computer</translation>
-<translation id="5179510805599951267">Non in <ph name="ORIGINAL_LANGUAGE"/>? Segnala questo errore</translation>
+<translation id="5179510805599951267">Non in <ph name="ORIGINAL_LANGUAGE" />? Segnala questo errore</translation>
<translation id="5190835502935405962">Barra dei Preferiti</translation>
+<translation id="5199729219167945352">Esperimenti</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">Conferma navigazione</translation>
<translation id="5299298092464848405">Errore durante l'analisi del criterio</translation>
+<translation id="5316812925700871227">Ruota in senso antiorario</translation>
<translation id="5317780077021120954">Salva</translation>
<translation id="536296301121032821">Archiviazione delle impostazioni criterio non riuscita</translation>
-<translation id="5439770059721715174">Errore di convalida dello schema in &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Errore di convalida dello schema in "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Timestamp del criterio errato</translation>
<translation id="5470861586879999274">&amp;Ripeti modifica</translation>
<translation id="5509780412636533143">Preferiti gestiti</translation>
<translation id="5523118979700054094">Nome norma</translation>
<translation id="552553974213252141">Il testo è stato estratto correttamente?</translation>
<translation id="5540224163453853">Impossibile trovare l'articolo richiesto.</translation>
+<translation id="5556459405103347317">Ricarica</translation>
<translation id="5565735124758917034">Attivo</translation>
<translation id="560412284261940334">Gestione non supportata</translation>
<translation id="5629630648637658800">Caricamento delle impostazioni criterio non riuscito</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Utente corrente</translation>
<translation id="5813119285467412249">&amp;Ripeti aggiunta</translation>
<translation id="5872918882028971132">Suggerimenti per i genitori</translation>
-<translation id="587701087903783706">Chiudi visualizzazione ottimizzata per i dispositivi mobili</translation>
<translation id="59107663811261420">Questo tipo di carta non è supportato in Google Payments per questo commerciante. Seleziona un'altra carta.</translation>
+<translation id="5975083100439434680">Diminuisci lo zoom</translation>
<translation id="5989320800837274978">Non sono stati specificati né server proxy fissi né un URL script .pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Chiudi</translation>
+<translation id="6060685159320643512">Attenzione, prova questi esperimenti a tuo rischio e pericolo</translation>
+<translation id="6151417162996330722">Il certificato del server ha un periodo di validità troppo lungo.</translation>
<translation id="6154808779448689242">Il token del criterio restituito non corrisponde al token corrente</translation>
<translation id="6165508094623778733">Ulteriori informazioni</translation>
<translation id="6259156558325130047">&amp;Ripeti ridisposizione</translation>
-<translation id="6263376278284652872">Segnalibri di <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Segnalibri di <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Codice postale</translation>
<translation id="6337534724793800597">Filtra i criteri per nome</translation>
+<translation id="6387478394221739770">Ti interessano le nuove e straordinarie funzioni di Chrome? Prova il nostro canale beta all'indirizzo chrome.com/beta.</translation>
+<translation id="6426993025560594914">Tutti gli esperimenti sono disponibili sulla tua piattaforma.</translation>
<translation id="6445051938772793705">Paese</translation>
<translation id="6458467102616083041">Ignorato perché la ricerca predefinita è stata disattivata secondo la norma.</translation>
<translation id="647261751007945333">Norme dispositivo</translation>
<translation id="6512448926095770873">Esci dalla pagina</translation>
<translation id="6529602333819889595">&amp;Ripeti eliminazione</translation>
<translation id="6550675742724504774">Opzioni</translation>
-<translation id="6597614308054261376">Stai provando a visitare <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Al momento non è possibile eseguire il proxy della pagina tramite Risparmio dati.</translation>
-<translation id="6628463337424475685">Ricerca <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Stai provando a visitare <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Al momento non è possibile eseguire il proxy della pagina tramite Risparmio dati.</translation>
+<translation id="6628463337424475685">Ricerca <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Questa norma è obsoleta.</translation>
<translation id="6646897916597483132">Inserisci il codice CVC di quattro cifre indicato sulla parte anteriore della carta</translation>
+<translation id="674375294223700098">Errore sconosciuto del certificato del server.</translation>
<translation id="6753269504797312559">Valore norma</translation>
<translation id="6831043979455480757">Traduci</translation>
<translation id="6839929833149231406">Area</translation>
<translation id="6874604403660855544">&amp;Ripeti aggiunta</translation>
<translation id="6891596781022320156">Il livello della norma non è supportato.</translation>
<translation id="6915804003454593391">Utente:</translation>
+<translation id="6957887021205513506">Il certificato del server risulta essere un falso.</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6965978654500191972">Dispositivo</translation>
<translation id="6970216967273061347">Distretto</translation>
<translation id="6973656660372572881">Sono stati specificati sia i server proxy fissi che un URL script .pac.</translation>
<translation id="6980028882292583085">Avviso JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Hai tentato di visitare il sito <ph name="DOMAIN" />, ma il server ha presentato un certificato con periodo di validità troppo lungo per poter essere ritenuto attendibile.</translation>
<translation id="7087282848513945231">Contea</translation>
-<translation id="7108649287766967076">Traduzione in <ph name="TARGET_LANGUAGE"/> non riuscita.</translation>
+<translation id="7108649287766967076">Traduzione in <ph name="TARGET_LANGUAGE" /> non riuscita.</translation>
<translation id="7139724024395191329">Emirato</translation>
+<translation id="7179921470347911571">Riavvia ora</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="7186367841673660872">Questa pagina è stata tradotta da<ph name="ORIGINAL_LANGUAGE" />a<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Cerca <ph name="SEARCH_TERMS"/> su <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Cerca <ph name="SEARCH_TERMS" /> su <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">Impossibile stabilire una connessione privata con il sito <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perché data e ora del computer (<ph name="DATE_AND_TIME" />) sono sbagliate.</translation>
<translation id="7275334191706090484">Preferiti gestiti</translation>
<translation id="7298195798382681320">Consigliate</translation>
<translation id="7334320624316649418">&amp;Ripeti ridisposizione</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obbligatoria</translation>
<translation id="7542995811387359312">La compilazione automatica della carta di credito è disattivata perché questo modulo non utilizza una connessione sicura.</translation>
-<translation id="7568593326407688803">Questa pagina è in<ph name="ORIGINAL_LANGUAGE"/>Vuoi tradurla?</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="7568593326407688803">Questa pagina è in<ph name="ORIGINAL_LANGUAGE" />Vuoi tradurla?</translation>
<translation id="7569952961197462199">Rimuovere la carta di credito da Chrome?</translation>
-<translation id="7600965453749440009">Non tradurre mai <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Il valore non è compreso nell'intervallo (<ph name="VALUE"/>).</translation>
+<translation id="7592362899630581445">Il certificato del server vìola i vincoli relativi ai nomi.</translation>
+<translation id="7600965453749440009">Non tradurre mai <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Il valore non è compreso nell'intervallo (<ph name="VALUE" />).</translation>
+<translation id="7674629440242451245">Ti interessano le nuove e straordinarie funzioni di Chrome? Prova il nostro canale Dev all'indirizzo chrome.com/dev.</translation>
<translation id="7752995774971033316">Non gestito</translation>
+<translation id="7761701407923456692">Il certificato del server non corrisponde all'URL.</translation>
<translation id="777702478322588152">Prefettura</translation>
<translation id="7791543448312431591">Aggiungi</translation>
<translation id="7805768142964895445">Stato</translation>
<translation id="7813600968533626083">Rimuovere il suggerimento per i moduli da Chrome?</translation>
<translation id="7887683347370398519">Controlla il tuo codice CVC e riprova</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Il certificato del server non è ancora valido.</translation>
<translation id="7956713633345437162">Preferiti su disp. mobili</translation>
<translation id="7961015016161918242">Mai</translation>
<translation id="7977590112176369853">&lt;inserisci query&gt;</translation>
-<translation id="7983301409776629893">Traduci sempre <ph name="ORIGINAL_LANGUAGE"/> in <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Traduci sempre <ph name="ORIGINAL_LANGUAGE" /> in <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Preferiti desktop</translation>
<translation id="7995512525968007366">Non specificato</translation>
-<translation id="8034522405403831421">Questa pagina è in <ph name="SOURCE_LANGUAGE"/>. Tradurla in <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Override aziendale</translation>
+<translation id="8034522405403831421">Questa pagina è in <ph name="SOURCE_LANGUAGE" />. Tradurla in <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Impossibile visualizzare l'articolo.</translation>
<translation id="8091372947890762290">Attivazione in attesa sul server</translation>
<translation id="8194797478851900357">&amp;Annulla spostamento</translation>
-<translation id="8201077131113104583">URL di aggiornamento non valido per l'estensione con ID &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">URL di aggiornamento non valido per l'estensione con ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Non salvare</translation>
<translation id="8218327578424803826">Posizione assegnata:</translation>
<translation id="8249320324621329438">Ultimo recupero:</translation>
+<translation id="8294431847097064396">Origine</translation>
<translation id="8308427013383895095">La traduzione non è riuscita a causa di un problema con la connessione di rete.</translation>
<translation id="8311778656528046050">Vuoi ricaricare questa pagina?</translation>
<translation id="8349305172487531364">Barra dei Preferiti</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Si applica a</translation>
<translation id="8530504477309582336">Questo tipo di carta non è supportato in Google Payments. Seleziona un'altra carta.</translation>
<translation id="8553075262323480129">La traduzione non è riuscita perché non è stato possibile determinare la lingua della pagina.</translation>
-<translation id="8571890674111243710">Traduzione della pagina in <ph name="LANGUAGE"/> in corso...</translation>
+<translation id="8559762987265718583">Impossibile stabilire una connessione privata con il sito <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perché data e ora del dispositivo (<ph name="DATE_AND_TIME" />) sono sbagliate.</translation>
+<translation id="8571890674111243710">Traduzione della pagina in <ph name="LANGUAGE" /> in corso...</translation>
+<translation id="8647750283161643317">Ripristina i valori predefiniti per tutto</translation>
<translation id="8713130696108419660">Firma iniziale non valida</translation>
<translation id="8725066075913043281">Riprova</translation>
+<translation id="8738058698779197622">Per poter stabilire una connessione protetta, l'orologio deve essere impostato correttamente perché i certificati utilizzati dai siti web per identificarsi sono validi soltanto per determinati periodi di tempo. L'orologio del dispositivo è sbagliato, pertanto Chromium non può verificare i certificati.</translation>
<translation id="8790007591277257123">&amp;Ripeti eliminazione</translation>
<translation id="8804164990146287819">Norme sulla privacy</translation>
+<translation id="8820817407110198400">Segnalibri</translation>
<translation id="8824019021993735287">Al momento non è possibile verificare la carta in Chrome. Riprova più tardi.</translation>
<translation id="8834246243508017242">Attiva Compilazione automatica utilizzando Contatti…</translation>
<translation id="883848425547221593">Altri Preferiti</translation>
+<translation id="884923133447025588">Nessun sistema di revoca trovato.</translation>
<translation id="8866481888320382733">Errore durante l'analisi delle impostazioni criterio</translation>
<translation id="8876793034577346603">Analisi della configurazione di rete non riuscita.</translation>
<translation id="8891727572606052622">Modalità proxy non valida.</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/>: esegui comando <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Spiacenti, questo esperimento non è disponibile sulla tua piattaforma.</translation>
+<translation id="8903921497873541725">Aumenta lo zoom</translation>
+<translation id="8932102934695377596">L'orologio è indietro</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" />: esegui comando <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Il certificato del server è scaduto.</translation>
<translation id="8988760548304185580">Inserisci la data di scadenza e il codice CVC di tre cifre indicato sul retro della carta</translation>
-<translation id="9020542370529661692">Questa pagina è stata tradotta in <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">I contrassegni che si applicano a livello di sistema possono essere impostati solo dal proprietario: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Questa pagina è stata tradotta in <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Hai tentato di connetterti a <ph name="DOMAIN" />, ma il server ha presentato un certificato scaduto.</translation>
<translation id="9125941078353557812">Inserisci il codice CVC di tre cifre indicato sul retro della carta</translation>
<translation id="9137013805542155359">Mostra originale</translation>
<translation id="9148507642005240123">&amp;Annulla modifica</translation>
<translation id="9154176715500758432">Rimani su questa pagina</translation>
<translation id="9170848237812810038">&amp;Annulla</translation>
+<translation id="917450738466192189">Il certificato del server non è valido.</translation>
+<translation id="9187827965378254003">Spiacenti, sembra che al momento non ci siano esperimenti disponibili.</translation>
<translation id="9207861905230894330">Impossibile aggiungere l'articolo.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">CANCELLA MODULO</translation>
+<translation id="988159990683914416">Build</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_iw.xtb b/chromium/components/strings/components_strings_iw.xtb
index 27ae040dedd..68ff96e737b 100644
--- a/chromium/components/strings/components_strings_iw.xtb
+++ b/chromium/components/strings/components_strings_iw.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="iw">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="iw">
+<translation id="1032854598605920125">סובב בכיוון השעון</translation>
<translation id="1055184225775184556">&amp;ביטול הוספה</translation>
<translation id="106701514854093668">סימניות שולחן עבודה</translation>
-<translation id="1103523840287552314">תרגם <ph name="LANGUAGE"/> תמיד</translation>
+<translation id="1080116354587839789">התאם לרוחב</translation>
+<translation id="1103523840287552314">תרגם <ph name="LANGUAGE" /> תמיד</translation>
<translation id="1113869188872983271">&amp;ביטול של שינוי סדר</translation>
<translation id="111844081046043029">האם אתה בטוח שברצונך לצאת מדף זה?</translation>
<translation id="112840717907525620">הקובץ השמור של המדיניות תקין</translation>
<translation id="1132774398110320017">‏הגדרות מילוי אוטומטי של Chrome...</translation>
-<translation id="1152921474424827756">גש אל <ph name="BEGIN_LINK"/>עותק בקובץ שמור<ph name="END_LINK"/> של <ph name="URL"/></translation>
+<translation id="1150979032973867961">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. אישור האבטחה שלו לא נחשב כמהימן על ידי מערכת ההפעלה של המחשב. ייתכן שהסיבה לכך היא תצורה שגויה או תוקף המיירט את החיבור שלך.</translation>
+<translation id="1152921474424827756">גש אל <ph name="BEGIN_LINK" />עותק בקובץ שמור<ph name="END_LINK" /> של <ph name="URL" /></translation>
+<translation id="121201262018556460">ניסית להגיע אל <ph name="DOMAIN" />, אך השרת הציג אישור המכיל מפתח חלש. ייתכן שתוקף פרץ את המפתח הפרטי, והשרת אינו השרת שרצית (ייתכן שאתה מתקשר עם תוקף).</translation>
<translation id="1227224963052638717">מדיניות לא ידועה.</translation>
<translation id="1227633850867390598">הסתר ערך</translation>
<translation id="1228893227497259893">מזהה יישות שגוי</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">דומיין הרשמה:</translation>
<translation id="1344588688991793829">‏הגדרות מילוי אוטומטי של Chromium...</translation>
<translation id="1426410128494586442">כן</translation>
+<translation id="1430915738399379752">הדפס</translation>
<translation id="1455235771979731432">הייתה בעיה באימות הכרטיס. בדוק את החיבור לאינטרנט ונסה שוב.</translation>
<translation id="1491151370853475546">טען מחדש דף זה</translation>
<translation id="1549470594296187301">‏JavaScript צריך להיות מופעל כדי להשתמש בתכונה זו.</translation>
-<translation id="1639239467298939599">טוען</translation>
<translation id="1640180200866533862">מדיניות משתמשים</translation>
<translation id="1644184664548287040">תצורת הרשת אינה חוקית ולא ניתן לייבא אותה.</translation>
-<translation id="1693754753824026215">הדף ב-<ph name="SITE"/> אומר:</translation>
+<translation id="1655462015569774233">{1,plural, =1{השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />; התוקף של אישור האבטחה שלו פג אתמול. ייתכן שהסיבה לכך היא הגדרה שגויה או שתוקף מיירט את החיבור שלך. התאריך המוגדר כעת בשעון המחשב שלך הוא <ph name="CURRENT_DATE" />. האם זה נכון? אם לא, עליך לכוון את שעון המערכת ולאחר מכן לרענן את הדף הזה.}two{השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />; התוקף של אישור האבטחה שלו פג לפני יומיים. ייתכן שהסיבה לכך היא הגדרה שגויה או שתוקף מיירט את החיבור שלך. התאריך המוגדר כעת בשעון המחשב שלך הוא <ph name="CURRENT_DATE" />. האם זה נכון? אם לא, עליך לכוון את שעון המערכת ולאחר מכן לרענן את הדף הזה.}many{השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />; התוקף של אישור האבטחה שלו פג לפני # ימים. ייתכן שהסיבה לכך היא הגדרה שגויה או שתוקף מיירט את החיבור שלך. התאריך המוגדר כעת בשעון המחשב שלך הוא <ph name="CURRENT_DATE" />. האם זה נכון? אם לא, עליך לכוון את שעון המערכת ולאחר מכן לרענן את הדף הזה.}other{השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />; התוקף של אישור האבטחה שלו פג לפני # ימים. ייתכן שהסיבה לכך היא הגדרה שגויה או שתוקף מיירט את החיבור שלך. התאריך המוגדר כעת בשעון המחשב שלך הוא <ph name="CURRENT_DATE" />. האם זה נכון? אם לא, עליך לכוון את שעון המערכת ולאחר מכן לרענן את הדף הזה.}}</translation>
+<translation id="168841957122794586">אישור השרת מכיל מפתח הצפנה חלש.</translation>
+<translation id="1693754753824026215">הדף ב-<ph name="SITE" /> אומר:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. אישור האבטחה שלו לא נחשב כמהימן על ידי מערכת ההפעלה של המכשיר. ייתכן שהסיבה לכך היא תצורה שגויה או תוקף המיירט את החיבור שלך.</translation>
<translation id="1821930232296380041">הבקשה או הפרמטרים של הבקשה אינם חוקיים</translation>
-<translation id="1853748787962613237">הצגת הפריט נכשלה.</translation>
<translation id="1871208020102129563">‏שרת ה-Proxy מוגדר להשתמש בשרתי Proxy קבועים, לא בכתובת אתר של סקריפט ‎.Pac</translation>
-<translation id="1875753206475436906">סוג היוריסטיקה: <ph name="HEURISTIC_TYPE"/>
- סוג שרת: <ph name="SERVER_TYPE"/>
- חתימת שדה: <ph name="FIELD_SIGNATURE"/>
- חתימת טופס: <ph name="FORM_SIGNATURE"/>
- מזהה ניסוי: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">עבור ל-<ph name="LINK"/></translation>
-<translation id="1962204205936693436">סימניות של <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">עבור ל-<ph name="LINK" /></translation>
+<translation id="1962204205936693436">סימניות של <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">שגיאה בעריכה בסידרה</translation>
+<translation id="1974060860693918893">מתקדם</translation>
<translation id="2025186561304664664">‏שרת Proxy נקבע למוגדר אוטומטית.</translation>
<translation id="2025623846716345241">אשר טעינה מחדש</translation>
-<translation id="2030481566774242610">האם התכוונת ל-<ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">האם התכוונת ל-<ph name="LINK" />?</translation>
<translation id="2053553514270667976">מספר / מיקוד</translation>
<translation id="20817612488360358">‏נקבע שימוש בהגדרות שרת Proxy של מערכת אך בנוסף מצוינת גם תצורה מפורשת של שרת Proxy.</translation>
<translation id="2094505752054353250">אי התאמה בדומיינים</translation>
<translation id="2096368010154057602">מחלקה</translation>
<translation id="2113977810652731515">כרטיס</translation>
-<translation id="2114841414352855701">המערכת התעלמה משום שהמדיניות בוטלה על ידי <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">המערכת התעלמה משום שהמדיניות בוטלה על ידי <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">סימניות לנייד</translation>
+<translation id="2171101176734966184">ניסית להגיע אל <ph name="DOMAIN" /> אך השרת הציג אישור שנחתם באמצעות אלגוריתם חתימה חלש. כלומר, ייתכן שהרשאות האבטחה שהשרת הציג זויפו, וכן ייתכן שהשרת אינו השרת שרצית (ייתכן שאתה מתקשר עם תוקף).</translation>
<translation id="2181821976797666341">מדיניות</translation>
<translation id="2212735316055980242">לא נמצאה מדיניות</translation>
<translation id="2213606439339815911">מאחזר רשומות...</translation>
<translation id="225207911366869382">ערך זה הוצא משימוש עבור מדיניות זו.</translation>
<translation id="2262243747453050782">‏שגיאת HTTP</translation>
-<translation id="2270192940992995399">לא ניתן היה למצוא את הפריט.</translation>
-<translation id="2328300916057834155">המערכת התעלמה מסימניה לא חוקית באינדקס <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">ניסויים לא זמינים</translation>
+<translation id="229702904922032456">פג תוקפו של אישור שורש או אישור ביניים.</translation>
+<translation id="2328300916057834155">המערכת התעלמה מסימניה לא חוקית באינדקס <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">סימניות אחרות</translation>
<translation id="2359808026110333948">המשך</translation>
<translation id="2367567093518048410">רמה</translation>
+<translation id="2384307209577226199">ברירת מחדל של ארגון</translation>
+<translation id="2386255080630008482">אישור השרת נשלל.</translation>
<translation id="2392959068659972793">הצגת מדיניות ללא ערך מוגדר</translation>
<translation id="2396249848217231973">&amp;ביטול מחיקה</translation>
+<translation id="2413528052993050574">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. ייתכן שאישור האבטחה שלו בוטל. הסיבה לכך עשויה להיות הגדרה שגויה או תוקף המיירט את החיבור שלך.</translation>
<translation id="2455981314101692989">דף אינטרנט זה השבית מילוי אוטומטי של טופס זה.</translation>
<translation id="2479410451996844060">כתובת אתר לא חוקית של חיפוש</translation>
+<translation id="2491120439723279231">אישור השרת מכיל שגיאות.</translation>
<translation id="2495083838625180221">‏מנתח JSON</translation>
<translation id="2498091847651709837">סרוק כרטיס חדש</translation>
<translation id="2556876185419854533">&amp;ביטול עריכה</translation>
-<translation id="2581221116934462656">האם תרצה ש-<ph name="PRODUCT_NAME"/> יציע לתרגם דפים ב<ph name="LANGUAGE_NAME"/> מהאתר הזה בפעם הבאה?</translation>
+<translation id="2581221116934462656">האם תרצה ש-<ph name="PRODUCT_NAME" /> יציע לתרגם דפים ב<ph name="LANGUAGE_NAME" /> מהאתר הזה בפעם הבאה?</translation>
<translation id="2587841377698384444">‏מזהה ממשק API של ספרייה:</translation>
<translation id="2597378329261239068">מסמך זה מוגן באמצעות סיסמה. הזן סיסמה.</translation>
+<translation id="2625385379895617796">השעון שלך מקדים</translation>
<translation id="2639739919103226564">סטטוס:</translation>
+<translation id="2653659639078652383">שלח</translation>
<translation id="2704283930420550640">הערך לא תואם לפורמט.</translation>
<translation id="2721148159707890343">הבקשה בוצעה בהצלחה</translation>
+<translation id="2728127805433021124">האישור של השרת נחתם באמצעות אלגוריתם של חתימה חלשה.</translation>
<translation id="2774256287122201187">אתה רשאי להמשיך. אם תמשיך אל הדף, האזהרה הזו לא תופיע שוב למשך חמש דקות.</translation>
<translation id="277499241957683684">חסרה רשומת מכשיר</translation>
<translation id="2835170189407361413">נקה טופס</translation>
-<translation id="2855922900409897335">אמת את ה-<ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">אמת את ה-<ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">לשרת זה לא הייתה אפשרות להוכיח שהוא <ph name="DOMAIN" />; פג תוקפו של אישור האבטחה שלו. ייתכן שמצב זה נגרם בשל תצורה שגויה או שתוקף מיירט את החיבור שלך. שעון המחשב שלך מוגדר כעת ל-<ph name="CURRENT_TIME" />. האם השעה נכונה? אם לא, עליך לכוון את שעון המערכת ולאחר מכן לרענן דף זה.</translation>
+<translation id="2922350208395188000">לא ניתן לבדוק את אישור השרת.</translation>
+<translation id="2941952326391522266">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. אישור האבטחה שלו הוא מ-<ph name="DOMAIN2" />. ייתכן שהסיבה לכך היא תצורה שגויה או תוקף המיירט את החיבור שלך.</translation>
<translation id="2958431318199492670">‏תצורת הרשת אינה תואמת לתקן ONC. ייתכן שחלקים מהתצורה לא ייכללו בייבוא.</translation>
<translation id="2972581237482394796">&amp;בצע שנית</translation>
-<translation id="3010559122411665027">רשומה ברשימה &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">רשומה ברשימה "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">סוג המדיניות שגוי</translation>
<translation id="3105172416063519923">מזהה נכס:</translation>
<translation id="3145945101586104090">פענוח התגובה נכשל</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">אי</translation>
<translation id="3219579145727097045">‏הזן את תאריך סיום התוקף ו-CVC בן ארבע ספרות המופיע בחזית הכרטיס</translation>
-<translation id="3228969707346345236">התרגום נכשל כיוון שהדף כבר ב<ph name="LANGUAGE"/>.</translation>
+<translation id="3225919329040284222">השרת הציג אישור שאינו תואם את הציפיות המובנות. ציפיות אלה נכללות עבור אתרי אינטרנט מסוימים בעלי אבטחה גבוהה כדי להגן עליך.</translation>
+<translation id="3228969707346345236">התרגום נכשל כיוון שהדף כבר ב<ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;ביטול של שינוי סדר</translation>
+<translation id="3286538390144397061">הפעל מחדש כעת</translation>
<translation id="333371639341676808">מנע מדף זה ליצור דיאלוגים נוספים.</translation>
-<translation id="3369366829301677151">עדכן ואמת את ה-<ph name="CREDIT_CARD"/> שלך</translation>
+<translation id="3340978935015468852">הגדרות</translation>
+<translation id="3369192424181595722">שגיאת שעון</translation>
+<translation id="3369366829301677151">עדכן ואמת את ה-<ph name="CREDIT_CARD" /> שלך</translation>
<translation id="337363190475750230">ניהול התצורה בוטל</translation>
<translation id="3377188786107721145">שגיאה בניתוח המדיניות</translation>
<translation id="3380365263193509176">שגיאה לא ידועה</translation>
<translation id="3380864720620200369">מזהה לקוח:</translation>
<translation id="3427342743765426898">&amp;ביצוע מחדש של עריכה</translation>
+<translation id="3435896845095436175">הפעל</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">מרווח אחזור:</translation>
+<translation id="3462200631372590220">הסתר פרטים מתקדמים</translation>
+<translation id="3528171143076753409">אישור השרת אינו מהימן.</translation>
<translation id="3542684924769048008">השתמש בסיסמה עבור:</translation>
<translation id="3583757800736429874">&amp;ביצוע מחדש של העברה</translation>
<translation id="3623476034248543066">הצג ערך</translation>
+<translation id="3648607100222897006">תכונות ניסיוניות אלה עשויות להשתנות, להפסיק לעבוד או להיעלם בכל עת. איננו מביעים כל אחריות לגבי ההשלכות של הפעלה של אחד מניסויים אלה, וייתכן אף שהדפדפן שלך יתלקח באופן ספונטני. צחוק בצד, הדפדפן עלול למחוק את כל הנתונים שלך, או שהאבטחה והפרטיות שלך ייפגעו בדרכים לא צפויות. כל ניסוי שתאפשר יהפוך לפעיל עבור כל המשתמשים בדפדפן זה. המשך בזהירות.</translation>
<translation id="3650584904733503804">האימות בוצע בהצלחה</translation>
<translation id="370665806235115550">טוען...</translation>
<translation id="3712624925041724820">אין מספיק רישיונות</translation>
<translation id="3739623965217189342">קישור שהעתקת</translation>
<translation id="375403751935624634">התרגום נכשל עקב שגיאת שרת.</translation>
<translation id="385051799172605136">חזור</translation>
+<translation id="3858027520442213535">עדכן את התאריך והשעה</translation>
<translation id="3884278016824448484">מזהה מכשיר מתנגש</translation>
<translation id="3885155851504623709">קהילה</translation>
<translation id="3934680773876859118">‏הטעינה של מסמך PDF נכשלה</translation>
<translation id="3963721102035795474">מצב קורא</translation>
<translation id="4030383055268325496">&amp;ביטול הוספה</translation>
-<translation id="4058922952496707368">מפתח &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">אזהרה</translation>
+<translation id="4058922952496707368">מפתח "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">‏תצורת ה-Proxy מוגדרת להשתמש בכתובת אתר של סקריפט מסוג ‎.Pac ולא בשרתי Proxy קבועים.</translation>
<translation id="409504436206021213">אל תטען מחדש</translation>
<translation id="4103249731201008433">המספר הסידורי של המכשיר אינו חוקי</translation>
@@ -118,40 +146,60 @@
<translation id="4258748452823770588">חתימה שגויה</translation>
<translation id="4269787794583293679">(אין שם משתמש)</translation>
<translation id="4300246636397505754">הצעות להורים</translation>
-<translation id="4372948949327679948">צפוי ערך מסוג <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">לא ניתן היה למצוא את הפריט</translation>
+<translation id="4372948949327679948">צפוי ערך מסוג <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">ניסית להשיג את <ph name="DOMAIN" />, אך האישור שהשרת הציג בוטל על ידי המנפיק שלו. פירוש הדבר שאין כל אפשרות לתת אמון באישורי האבטחה שהשרת הציג. ייתכן שאתה מתקשר עם תוקף.</translation>
+<translation id="4394049700291259645">השבת</translation>
+<translation id="4424024547088906515">‏השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. אישור האבטחה שלו לא נחשב כמהימן על ידי Chrome. ייתכן שהסיבה לכך היא תצורה שגויה או תוקף המיירט את החיבור שלך.</translation>
<translation id="443673843213245140">‏השימוש בשרת Proxy הושבת, אך צויינה תצורת שרת Proxy מפורשת.</translation>
-<translation id="4506176782989081258">שגיאת אימות: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">שגיאת אימות: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">‏האם להסיר את הכתובת מ-Chrome?</translation>
<translation id="4594403342090139922">&amp;ביטול מחיקה</translation>
<translation id="4607653538520819196">‏לא ניתן להעביר את הדף הזה דרך שרת proxy באמצעות חוסך הנתונים (Data Saver).</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />; אישור האבטחה שלו מכיל שגיאות. ייתכן שהסיבה לכך היא הגדרה שגויה או תוקף המיירט את החיבור שלך.</translation>
<translation id="4726672564094551039">טען מדיניות מחדש</translation>
+<translation id="4728558894243024398">פלטפורמה</translation>
+<translation id="4771973620359291008">‏אירעה שגיאה לא מוכרת.
+
+
+1240185477879256427אתר
+Del</translation>
<translation id="4800132727771399293">‏בדוק את תאריך התפוגה ואת ה-CVC ונסה שוב</translation>
<translation id="4813512666221746211">שגיאת רשת</translation>
+<translation id="4816492930507672669">התאמה לדף</translation>
<translation id="4850886885716139402">הצג</translation>
-<translation id="4923417429809017348">דף זה תורגם משפה לא ידועה ל<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">דף זה תורגם משפה לא ידועה ל<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">יש לציין ערך זה.</translation>
<translation id="4968547170521245791">‏לא ניתן להעביר דרך שרת proxy</translation>
-<translation id="498957508165411911">האם לתרגם מ<ph name="ORIGINAL_LANGUAGE"/> ל<ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">האם לתרגם מ<ph name="ORIGINAL_LANGUAGE" /> ל<ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">האחסון המשמש כגיבוי אינו תקין</translation>
<translation id="5031870354684148875">‏מידע על Google Translate</translation>
+<translation id="5045550434625856497">סיסמה שגויה</translation>
+<translation id="5087286274860437796">האישור של השרת אינו תקף כעת.</translation>
<translation id="5089810972385038852">מדינה</translation>
+<translation id="5094747076828555589">‏השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. אישור האבטחה שלו לא נחשב כמהימן על ידי Chromium. ייתכן שהסיבה לכך היא תצורה שגויה או תוקף המיירט את החיבור שלך.</translation>
<translation id="5095208057601539847">פרובינציה</translation>
<translation id="5145883236150621069">קיים קוד שגיאה בתגובת המדיניות</translation>
<translation id="5172758083709347301">מכונה</translation>
-<translation id="5179510805599951267">לא ב<ph name="ORIGINAL_LANGUAGE"/>? דווח על שגיאה זו</translation>
+<translation id="5179510805599951267">לא ב<ph name="ORIGINAL_LANGUAGE" />? דווח על שגיאה זו</translation>
<translation id="5190835502935405962">סרגל הסימניות</translation>
+<translation id="5199729219167945352">ניסויים</translation>
+<translation id="5251803541071282808">ענן</translation>
<translation id="5295309862264981122">אשר ניווט</translation>
<translation id="5299298092464848405">שגיאה בניתוח המדיניות</translation>
+<translation id="5316812925700871227">סובב נגד כיוון השעון</translation>
<translation id="5317780077021120954">שמור</translation>
<translation id="536296301121032821">אחסון הגדרות המדיניות נכשל</translation>
-<translation id="5439770059721715174">שגיאת אימות סכימה ב-&quot;<ph name="ERROR_PATH"/>&quot;‏: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">שרת זה לא הצליח להוכיח שהוא <ph name="DOMAIN" />; אישור האבטחה שלו אינו תקף כעת. הסיבה לכך עשויה להיות תצורה שגויה או שתוקף מיירט את החיבור שלך.</translation>
+<translation id="5439770059721715174">שגיאת אימות סכימה ב-"<ph name="ERROR_PATH" />"‏: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">חותמת הזמן של המדיניות שגויה</translation>
<translation id="5470861586879999274">&amp;ביצוע מחדש של עריכה</translation>
<translation id="5509780412636533143">סימניות מנוהלות</translation>
<translation id="5523118979700054094">שם מדיניות</translation>
<translation id="552553974213252141">האם הטקסט נשלף כראוי?</translation>
<translation id="5540224163453853">לא ניתן היה למצוא את הפריט המבוקש.</translation>
+<translation id="5556459405103347317">טען שוב</translation>
<translation id="5565735124758917034">פעיל</translation>
<translation id="560412284261940334">ניהול אינו נתמך</translation>
<translation id="5629630648637658800">טעינת הגדרות המדיניות נכשלה</translation>
@@ -159,46 +207,56 @@
<translation id="5720705177508910913">משתמש נוכחי:</translation>
<translation id="5813119285467412249">&amp;ביצוע מחדש של הוספה</translation>
<translation id="5872918882028971132">הצעות להורים</translation>
-<translation id="587701087903783706">סגור את התצוגה הידידותית לנייד</translation>
<translation id="59107663811261420">‏סוג הכרטיס הזה אינו נתמך על ידי Google Payments אצל הסוחר הזה. בחר כרטיס אחר.</translation>
+<translation id="5975083100439434680">התרחק</translation>
<translation id="5989320800837274978">‏לא צוינו שרתי Proxy קבועים ולא כתובת אתר של סקריפט ‎.pac</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">סגור</translation>
+<translation id="6060685159320643512">זהירות, ניסויים אלה עלולים לנשוך</translation>
+<translation id="6151417162996330722">תקופת התוקף של אישור השרת ארוכה מדי.</translation>
<translation id="6154808779448689242">אסימון המדיניות שהוחזר אינו תואם לאסימון הנוכחי</translation>
<translation id="6165508094623778733">למידע נוסף</translation>
<translation id="6259156558325130047">&amp;ביצוע מחדש של שינוי סדר</translation>
-<translation id="6263376278284652872">סימניות <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">סימניות <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">מיקוד</translation>
<translation id="6337534724793800597">סנן מדיניות לפי שם</translation>
+<translation id="6387478394221739770">‏מעוניין בתכונות חדשות ומגניבות של Chrome? נסה את ערוץ הביטא שלנו בכתובת chrome.com/beta.</translation>
+<translation id="6426993025560594914">כל הניסויים זמינים בפלטפורמה שלך!</translation>
<translation id="6445051938772793705">ארץ</translation>
<translation id="6458467102616083041">המערכת התעלמה מערך מדיניות זה, משום שלפי המדיניות, חיפוש ברירת המחדל מושבת.</translation>
<translation id="647261751007945333">מדיניות המכשיר</translation>
<translation id="6512448926095770873">צא מדף זה</translation>
<translation id="6529602333819889595">&amp;ביצוע מחדש של מחיקה</translation>
<translation id="6550675742724504774">אפשרויות</translation>
-<translation id="6597614308054261376">‏אתה מנסה ליצור קשר עם <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. לא ניתן כעת להעביר את הדף הזה דרך שרת proxy באמצעות חוסך הנתונים (Data Saver).</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> חיפוש</translation>
+<translation id="6597614308054261376">‏אתה מנסה ליצור קשר עם <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. לא ניתן כעת להעביר את הדף הזה דרך שרת proxy באמצעות חוסך הנתונים (Data Saver).</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> חיפוש</translation>
<translation id="6644283850729428850">מדיניות זו אינה בתוקף.</translation>
<translation id="6646897916597483132">‏הזן את ה-CVC בן ארבע הספרות המופיע בחזית הכרטיס</translation>
+<translation id="674375294223700098">שגיאת אישור שרת לא ידוע.</translation>
<translation id="6753269504797312559">ערך מדיניות</translation>
<translation id="6831043979455480757">תרגם</translation>
<translation id="6839929833149231406">אזור</translation>
<translation id="6874604403660855544">&amp;ביצוע מחדש של הוספה</translation>
<translation id="6891596781022320156">רמת המדיניות אינה נתמכת.</translation>
<translation id="6915804003454593391">משתמש:</translation>
+<translation id="6957887021205513506">נראה שהאישור של השרת מזויף.</translation>
<translation id="6965382102122355670">אישור</translation>
<translation id="6965978654500191972">התקן</translation>
<translation id="6970216967273061347">מחוז</translation>
<translation id="6973656660372572881">‏צוינו שרתי Proxy קבועים וכתובת אתר של הסקריפט מסוג ‎.Pac</translation>
<translation id="6980028882292583085">‏התראת JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">ניסית להגיע אל <ph name="DOMAIN" />, אך השרת הציג אישור שתקופת התוקף שלו ארוכה מדי ולכן אינו מהימן.</translation>
<translation id="7087282848513945231">מחוז (בבריטניה ובאירלנד)</translation>
-<translation id="7108649287766967076">התרגום ל<ph name="TARGET_LANGUAGE"/> נכשל.</translation>
+<translation id="7108649287766967076">התרגום ל<ph name="TARGET_LANGUAGE" /> נכשל.</translation>
<translation id="7139724024395191329">אמירות</translation>
+<translation id="7179921470347911571">הפעל מחדש עכשיו</translation>
<translation id="7180611975245234373">רענן</translation>
<translation id="7182878459783632708">לא הוגדרה מדיניות</translation>
-<translation id="7186367841673660872">דף זה תורגם מ<ph name="ORIGINAL_LANGUAGE"/>ל<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="7186367841673660872">דף זה תורגם מ<ph name="ORIGINAL_LANGUAGE" />ל<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">חפש את <ph name="SEARCH_TERMS"/> ב-<ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">חפש את <ph name="SEARCH_TERMS" /> ב-<ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">לא ניתן ליצור חיבור פרטי אל <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> מפני שהתאריך והשעה (<ph name="DATE_AND_TIME" />) במחשב שלך שגויים.</translation>
<translation id="7275334191706090484">סימניות מנוהלות</translation>
<translation id="7298195798382681320">מומלצים</translation>
<translation id="7334320624316649418">&amp;ביצוע מחדש של שינוי סדר</translation>
@@ -209,31 +267,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">הכרחי</translation>
<translation id="7542995811387359312">מילוי אוטומטי של פרטי כרטיס אשראי מושבת כיוון שטופס זה אינו משתמש בחיבור מאובטח.</translation>
-<translation id="7568593326407688803">זהו דף ב<ph name="ORIGINAL_LANGUAGE"/>האם ברצונך לתרגם אותו?</translation>
+<translation id="7567204685887185387">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. ייתכן שאישור האבטחה שלו נופק כהונאה. הסיבה לכך עשויה להיות הגדרה שגויה או תוקף המיירט את החיבור שלך.</translation>
+<translation id="7568593326407688803">זהו דף ב<ph name="ORIGINAL_LANGUAGE" />האם ברצונך לתרגם אותו?</translation>
<translation id="7569952961197462199">‏האם להסיר את כרטיס האשראי מ-Chrome?</translation>
-<translation id="7600965453749440009">אל תתרגם לעולם <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">הערך מחוץ לטווח <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">אישור השרת מפר את אילוצי השמות.</translation>
+<translation id="7600965453749440009">אל תתרגם לעולם <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">הערך מחוץ לטווח <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">‏מעוניין בתכונות חדשות ומגניבות של Chrome? נסה את הערוץ שלנו למפתחים בכתובת chrome.com/dev.</translation>
<translation id="7752995774971033316">ללא ניהול</translation>
+<translation id="7761701407923456692">אישור השרת אינו תואם לכתובת האתר.</translation>
<translation id="777702478322588152">משטרת מחוז</translation>
<translation id="7791543448312431591">הוסף</translation>
<translation id="7805768142964895445">סטטוס</translation>
<translation id="7813600968533626083">‏האם להסיר מ-Chrome הצעות בשביל טפסים?</translation>
<translation id="7887683347370398519">‏בדוק את ה-CVC ונסה שוב</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">אישור השרת עדיין לא בתוקף.</translation>
<translation id="7956713633345437162">סימניות לנייד</translation>
<translation id="7961015016161918242">אף פעם</translation>
<translation id="7977590112176369853">&lt;הזן שאילתה&gt;</translation>
-<translation id="7983301409776629893">תרגם תמיד <ph name="ORIGINAL_LANGUAGE"/> ל<ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">תרגם תמיד <ph name="ORIGINAL_LANGUAGE" /> ל<ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">סימניות שולחן עבודה</translation>
<translation id="7995512525968007366">לא צוין</translation>
-<translation id="8034522405403831421">דף זה מוצג ב<ph name="SOURCE_LANGUAGE"/>. האם לתרגם אותו ל<ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">ביצוע שינויים בארגון</translation>
+<translation id="8034522405403831421">דף זה מוצג ב<ph name="SOURCE_LANGUAGE" />. האם לתרגם אותו ל<ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">הצגת הפריט נכשלה.</translation>
<translation id="8091372947890762290">ההפעלה ממתינה בשרת</translation>
<translation id="8194797478851900357">&amp;ביטול העברה</translation>
-<translation id="8201077131113104583">כתובת אתר לא חוקית לעדכון עבור תוסף עם המזהה &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">כתובת אתר לא חוקית לעדכון עבור תוסף עם המזהה "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">אל תשמור</translation>
<translation id="8218327578424803826">מיקום מוקצה:</translation>
<translation id="8249320324621329438">אוחזר לאחרונה:</translation>
+<translation id="8294431847097064396">מקור</translation>
<translation id="8308427013383895095">התרגום נכשל עקב בעיה בחיבור הרשת.</translation>
<translation id="8311778656528046050">האם אתה בטוח שברצונך לטעון מחדש דף זה?</translation>
<translation id="8349305172487531364">סרגל סימניות</translation>
@@ -242,25 +307,40 @@
<translation id="8488350697529856933">חל על</translation>
<translation id="8530504477309582336">‏סוג הכרטיס הזה אינו נתמך על ידי Google Payments. בחר כרטיס אחר.</translation>
<translation id="8553075262323480129">התרגום נכשל כיוון שלא הייתה אפשרות לקבוע את שפת הדף.</translation>
-<translation id="8571890674111243710">מתרגם דף ל<ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">לא ניתן ליצור חיבור פרטי אל <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> מפני שהתאריך והשעה (<ph name="DATE_AND_TIME" />) במכשיר שלך שגויים.</translation>
+<translation id="8571890674111243710">מתרגם דף ל<ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">אפס הכל לברירת המחדל</translation>
<translation id="8713130696108419660">חתימה ראשונית פגומה</translation>
<translation id="8725066075913043281">נסה שוב</translation>
+<translation id="8738058698779197622">‏כדי ליצור חיבור מאובטח, השעון צריך להיות מוגדר כהלכה. הסיבה לכך היא שהאישורים שבהם אתרים משתמשים כדי לזהות את עצמם תקפים רק למשך פרקי זמן מסוימים. מאחר שהשעון במכשיר שלך שגוי, Chromium לא יכול לאמת את האישורים האלו.</translation>
<translation id="8790007591277257123">&amp;ביצוע מחדש של מחיקה</translation>
<translation id="8804164990146287819">מדיניות פרטיות</translation>
+<translation id="8820817407110198400">סימניות</translation>
<translation id="8824019021993735287">‏Chrome לא הצליח לאמת את כרטיס הפעם. נסה שוב מאוחר יותר.</translation>
<translation id="8834246243508017242">הפעל מילוי אוטומטי באמצעות 'אנשי קשר'…</translation>
<translation id="883848425547221593">סימניות אחרות</translation>
+<translation id="884923133447025588">לא נמצא מנגנון ביטול</translation>
<translation id="8866481888320382733">שגיאה בניתוח הגדרות המדיניות</translation>
<translation id="8876793034577346603">ניתוח תצורת הרשת נכשל.</translation>
<translation id="8891727572606052622">‏מצב שרת Proxy לא חוקי.</translation>
-<translation id="8940229512486821554">הרץ את הפקודה של <ph name="EXTENSION_NAME"/>:‏ <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">מצטערים, ניסוי זה אינו זמין בפלטפורמה שלך.</translation>
+<translation id="8903921497873541725">התקרב</translation>
+<translation id="8932102934695377596">השעון שלך מאחר</translation>
+<translation id="8940229512486821554">הרץ את הפקודה של <ph name="EXTENSION_NAME" />:‏ <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">פג תוקפו של אישור השרת.</translation>
<translation id="8988760548304185580">‏הזן את תאריך סיום התוקף ו-CVC בן שלוש ספרות המופיע בגב הכרטיס</translation>
-<translation id="9020542370529661692">הדף הזה תורגם ל<ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">רק הבעלים יכול להגדיר סימונים החלים על כל המערכת: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">הדף הזה תורגם ל<ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">ניסית להגיע ל-<ph name="DOMAIN" />, אך השרת הציג אישור לא חוקי.</translation>
<translation id="9125941078353557812">‏הזן את ה-CVC בן שלוש הספרות המופיע בגב הכרטיס</translation>
<translation id="9137013805542155359">הצג מקור</translation>
<translation id="9148507642005240123">&amp;ביטול עריכה</translation>
<translation id="9154176715500758432">הישאר בדף זה</translation>
<translation id="9170848237812810038">&amp;ביטול</translation>
+<translation id="917450738466192189">אישור השרת לא חוקי.</translation>
+<translation id="9187827965378254003">אוי, נראה שאין ניסויים זמינים כרגע.</translation>
<translation id="9207861905230894330">הוספת הפריט נכשלה.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">נקה את הטופס</translation>
+<translation id="988159990683914416">גירסת מפתחים</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ja.xtb b/chromium/components/strings/components_strings_ja.xtb
index eabff2c7daa..c0a68f55c51 100644
--- a/chromium/components/strings/components_strings_ja.xtb
+++ b/chromium/components/strings/components_strings_ja.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ja">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ja">
+<translation id="1032854598605920125">時計回りに回転</translation>
<translation id="1055184225775184556">追加の取り消し(&amp;U)</translation>
<translation id="106701514854093668">パソコンのブックマーク</translation>
-<translation id="1103523840287552314"><ph name="LANGUAGE"/>を常に翻訳</translation>
+<translation id="1080116354587839789">ウィンドウ幅に合わせる</translation>
+<translation id="1103523840287552314"><ph name="LANGUAGE" />を常に翻訳</translation>
<translation id="1113869188872983271">順序変更の取り消し(&amp;U)</translation>
<translation id="111844081046043029">このページから移動してもよろしいですか?</translation>
<translation id="112840717907525620">ポリシー キャッシュは正常です</translation>
<translation id="1132774398110320017">Chrome の自動入力設定...</translation>
-<translation id="1152921474424827756"><ph name="URL"/> の<ph name="BEGIN_LINK"/>キャッシュ コピー<ph name="END_LINK"/>にアクセスします</translation>
+<translation id="1150979032973867961">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は、ご使用のパソコンのオペレーティング システムによって信頼されているものではありません。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
+<translation id="1152921474424827756"><ph name="URL" /> の<ph name="BEGIN_LINK" />キャッシュ コピー<ph name="END_LINK" />にアクセスします</translation>
+<translation id="121201262018556460"><ph name="DOMAIN" /> にアクセスしようとしましたが、サーバーから提示された証明書には脆弱な暗号鍵が含まれています。悪意のあるユーザーによって秘密鍵が破られた可能性があり、アクセスしようとしたサーバーとは異なるサーバーであるおそれがあります(悪意のあるユーザーと通信している可能性があります)。</translation>
<translation id="1227224963052638717">不明なポリシー。</translation>
<translation id="1227633850867390598">値を非表示</translation>
<translation id="1228893227497259893">エンティティ識別子が正しくありません</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">登録ドメイン:</translation>
<translation id="1344588688991793829">Chromium の自動入力設定...</translation>
<translation id="1426410128494586442">はい</translation>
+<translation id="1430915738399379752">印刷</translation>
<translation id="1455235771979731432">カードの確認中に問題が発生しました。インターネット接続を確認してから、もう一度お試しください。</translation>
<translation id="1491151370853475546">このページを再読み込み</translation>
<translation id="1549470594296187301">この機能を使用するには JavaScript を有効にする必要があります。</translation>
-<translation id="1639239467298939599">読み込み中</translation>
<translation id="1640180200866533862">ユーザー ポリシー</translation>
<translation id="1644184664548287040">ネットワーク設定が無効なためインポートできませんでした。</translation>
-<translation id="1693754753824026215">ページ <ph name="SITE"/> の記述:</translation>
+<translation id="1655462015569774233">{1,plural, =1{このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。セキュリティ証明書の有効期限が昨日付けで切れています。原因として、設定が不適切であるか、悪意のあるユーザーが接続を妨害していることが考えられます。パソコンの時計は現在 <ph name="CURRENT_DATE" />に設定されています。この時刻が正しくない場合は、システムの時計を修正した後このページを更新してください。}other{このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。セキュリティ証明書の有効期限が # 日前に切れています。原因として、設定が不適切であるか、悪意のあるユーザーが接続を妨害していることが考えられます。パソコンの時計は現在 <ph name="CURRENT_DATE" />に設定されています。この時刻が正しくない場合は、システムの時計を修正した後このページを更新してください。}}</translation>
+<translation id="168841957122794586">サーバー証明書に脆弱な暗号鍵が含まれています。</translation>
+<translation id="1693754753824026215">ページ <ph name="SITE" /> の記述:</translation>
+<translation id="1706954506755087368">{1,plural, =1{このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。セキュリティ証明書はおそらく明日以降に利用できるようになります。原因として、設定が不適切であるか、悪意のあるユーザーが接続を妨害していることが考えられます。}other{このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。セキュリティ証明書はおそらく # 日後から利用できるようになります。原因として、設定が不適切であるか、悪意のあるユーザーが接続を妨害していることが考えられます。}}</translation>
<translation id="1734864079702812349">AMEX</translation>
+<translation id="1763864636252898013">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は、ご使用のデバイスのオペレーティング システムによって信頼されているものではありません。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
<translation id="1821930232296380041">無効なリクエストまたはリクエスト パラメータです</translation>
-<translation id="1853748787962613237">記事を表示できませんでした。</translation>
<translation id="1871208020102129563">プロキシは .pac スクリプト URL ではなく固定プロキシ サーバーを使用するように設定されています。</translation>
-<translation id="1875753206475436906">ヒューリスティック タイプ: <ph name="HEURISTIC_TYPE"/>
- サーバー タイプ: <ph name="SERVER_TYPE"/>
- フィールドの署名: <ph name="FIELD_SIGNATURE"/>
- フォームの署名: <ph name="FORM_SIGNATURE"/>
- テスト用 ID: 「<ph name="EXPERIMENT_ID"/>」</translation>
-<translation id="194030505837763158"><ph name="LINK"/> に移動します</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> のブックマーク</translation>
+<translation id="194030505837763158"><ph name="LINK" /> に移動します</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> のブックマーク</translation>
<translation id="1973335181906896915">シリアル化エラーです</translation>
+<translation id="1974060860693918893">詳細設定</translation>
<translation id="2025186561304664664">プロキシは自動設定になっています。</translation>
<translation id="2025623846716345241">再読み込みに関する確認</translation>
-<translation id="2030481566774242610">もしかして: <ph name="LINK"/></translation>
+<translation id="2030481566774242610">もしかして: <ph name="LINK" /></translation>
<translation id="2053553514270667976">郵便番号</translation>
<translation id="20817612488360358">システム プロキシ設定を使用するように設定されていますが、明示的なプロキシの設定も指定されています。</translation>
<translation id="2094505752054353250">ドメインが一致しません</translation>
<translation id="2096368010154057602">県</translation>
<translation id="2113977810652731515">カード</translation>
-<translation id="2114841414352855701"><ph name="POLICY_NAME"/> によって上書きされるため無視されます。</translation>
+<translation id="2114841414352855701"><ph name="POLICY_NAME" /> によって上書きされるため無視されます。</translation>
+<translation id="2128531968068887769">ネイティブ クライアント</translation>
<translation id="213826338245044447">モバイルのブックマーク</translation>
+<translation id="2171101176734966184"><ph name="DOMAIN" /> にアクセスしようとしましたが、サーバーから提示された証明書は脆弱な署名アルゴリズムを使用して署名されています。これは、サーバーから提示されたセキュリティ認証情報が偽装されている可能性を示しており、アクセスしようとしたサーバーとは異なるサーバーであるおそれがあります(悪意のあるユーザーと通信している可能性があります)。</translation>
<translation id="2181821976797666341">ポリシー</translation>
<translation id="2212735316055980242">ポリシーが見つかりません</translation>
<translation id="2213606439339815911">エントリを取得しています...</translation>
<translation id="225207911366869382">この値は、このポリシーではサポートが終了しています。</translation>
<translation id="2262243747453050782">HTTP エラーです</translation>
-<translation id="2270192940992995399">記事が見つかりませんでした。</translation>
-<translation id="2328300916057834155">インデックス <ph name="ENTRY_INDEX"/> の無効なブックマークを無視しました</translation>
+<translation id="2282872951544483773">利用できない試験運用機能</translation>
+<translation id="229702904922032456">ルート証明書または中間証明書の期限が切れています。</translation>
+<translation id="2328300916057834155">インデックス <ph name="ENTRY_INDEX" /> の無効なブックマークを無視しました</translation>
<translation id="2354001756790975382">その他のブックマーク</translation>
<translation id="2359808026110333948">続行</translation>
<translation id="2367567093518048410">レベル</translation>
+<translation id="2384307209577226199">企業のデフォルト</translation>
+<translation id="2386255080630008482">サーバーの証明書は取り消されています。</translation>
<translation id="2392959068659972793">値が設定されていないポリシーを表示する</translation>
<translation id="2396249848217231973">削除の取り消し(&amp;U)</translation>
+<translation id="2413528052993050574">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は取り消されている可能性があります。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
<translation id="2455981314101692989">このウェブページでは、フォームへの自動入力が無効になっています。</translation>
<translation id="2479410451996844060">検索 URL が無効です。</translation>
+<translation id="2491120439723279231">サーバーの証明書にエラーがあります。</translation>
<translation id="2495083838625180221">JSON パーサー</translation>
<translation id="2498091847651709837">新しいカードをスキャン</translation>
<translation id="2556876185419854533">編集の取り消し(&amp;U)</translation>
-<translation id="2581221116934462656">次回、<ph name="PRODUCT_NAME"/> でこのサイトの<ph name="LANGUAGE_NAME"/>ページを翻訳しますか?</translation>
+<translation id="2581221116934462656">次回、<ph name="PRODUCT_NAME" /> でこのサイトの<ph name="LANGUAGE_NAME" />ページを翻訳しますか?</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">このドキュメントはパスワードで保護されています。パスワードを入力してください。</translation>
+<translation id="2625385379895617796">時計が進んでいます</translation>
<translation id="2639739919103226564">ステータス:</translation>
+<translation id="2653659639078652383">送信</translation>
<translation id="2704283930420550640">値が有効な形式ではありません。</translation>
<translation id="2721148159707890343">リクエストを正常に送信しました</translation>
+<translation id="2728127805433021124">サーバーの証明書は脆弱な署名アルゴリズムを使用して署名されています。</translation>
<translation id="2774256287122201187">続行できますが、このページに移動するとこの警告は今後 5 分間表示されません。</translation>
<translation id="277499241957683684">デバイス レコードがありません</translation>
<translation id="2835170189407361413">フォームをクリア</translation>
-<translation id="2855922900409897335"><ph name="CREDIT_CARD"/> の確認</translation>
+<translation id="2855922900409897335"><ph name="CREDIT_CARD" /> の確認</translation>
+<translation id="2915500479781995473">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。セキュリティ証明書の期限が切れています。原因として、設定が不適切か、悪意のあるユーザーが接続を妨害している可能性があります。パソコンの時計は現在 <ph name="CURRENT_TIME" /> に設定されています。この時刻が正しくない場合は、システムの時計を修正して、このページを更新してください。</translation>
+<translation id="2922350208395188000">サーバーの証明書を確認できません。</translation>
+<translation id="2941952326391522266">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は <ph name="DOMAIN2" /> から発行されています。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
<translation id="2958431318199492670">ネットワーク設定が ONC 標準に準拠していません。設定の一部がインポートされない可能性があります。</translation>
<translation id="2972581237482394796">やり直し(&amp;R)</translation>
-<translation id="3010559122411665027">リスト エントリ「<ph name="ENTRY_INDEX"/>」: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">リスト エントリ「<ph name="ENTRY_INDEX" />」: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">ポリシー タイプが間違っています</translation>
<translation id="3105172416063519923">アセット ID:</translation>
<translation id="3145945101586104090">応答をデコードできませんでした</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">島</translation>
<translation id="3219579145727097045">カードの表側に記載されている有効期限と 4 桁の CVC を入力します</translation>
-<translation id="3228969707346345236">このページは既に<ph name="LANGUAGE"/>なので、翻訳できません。</translation>
+<translation id="3225919329040284222">サーバーの提示した証明書が、組み込まれている想定の証明書と一致しません。これらの想定の証明書は、ユーザー保護のため、特定の安全性の高いウェブサイトについて用意されています。</translation>
+<translation id="3228969707346345236">このページは既に<ph name="LANGUAGE" />なので、翻訳できません。</translation>
<translation id="3270847123878663523">順序変更の取り消し(&amp;U)</translation>
+<translation id="3286538390144397061">今すぐ再起動</translation>
<translation id="333371639341676808">このページでこれ以上ダイアログボックスを生成しない</translation>
-<translation id="3369366829301677151"><ph name="CREDIT_CARD"/> の更新と確認</translation>
+<translation id="3340978935015468852">設定</translation>
+<translation id="3369192424181595722">時計のエラー</translation>
+<translation id="3369366829301677151"><ph name="CREDIT_CARD" /> の更新と確認</translation>
<translation id="337363190475750230">プロビジョニングが解除されました</translation>
<translation id="3377188786107721145">ポリシー解析エラーです</translation>
<translation id="3380365263193509176">不明なエラー</translation>
<translation id="3380864720620200369">クライアント ID:</translation>
<translation id="3427342743765426898">編集のやり直し(&amp;R)</translation>
+<translation id="3435896845095436175">有効にする</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">取得間隔:</translation>
+<translation id="3462200631372590220">詳細情報を表示しない</translation>
+<translation id="3528171143076753409">サーバーの証明書を信頼できません。</translation>
<translation id="3542684924769048008">次のパスワードを使用:</translation>
<translation id="3583757800736429874">移動のやり直し(&amp;R)</translation>
<translation id="3623476034248543066">値を表示</translation>
+<translation id="3648607100222897006">この試験運用機能は、随時変更、中断、提供中止されることがあります。これらの機能のいずれかを有効にした場合に生じる結果について、Google は一切保証しません。ブラウザによってすべてのデータが削除されたり、予期せぬ方法でセキュリティやプライバシーが侵害されたりする可能性があります。有効にした試験運用機能は同じブラウザを使用する全ユーザーに対して有効になります。続行する場合は十分ご注意ください。</translation>
<translation id="3650584904733503804">検証が正常に完了しました</translation>
<translation id="370665806235115550">読み込み中...</translation>
<translation id="3712624925041724820">ライセンスを使い切りました</translation>
<translation id="3739623965217189342">コピーしたリンク</translation>
<translation id="375403751935624634">サーバー エラーのため翻訳できませんでした。</translation>
<translation id="385051799172605136">戻る</translation>
+<translation id="3858027520442213535">日時を更新</translation>
<translation id="3884278016824448484">競合するデバイス識別子です</translation>
<translation id="3885155851504623709">教区</translation>
<translation id="3934680773876859118">PDF ドキュメントを読み込むことができませんでした</translation>
<translation id="3963721102035795474">リーダーモード</translation>
<translation id="4030383055268325496">追加の取り消し(&amp;U)</translation>
-<translation id="4058922952496707368">キー「<ph name="SUBKEY"/>」: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">警告</translation>
+<translation id="4058922952496707368">キー「<ph name="SUBKEY" />」: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">プロキシは固定プロキシ サーバーではなく .pac スクリプト URL を使用するように設定されています。</translation>
<translation id="409504436206021213">再読み込みしない</translation>
<translation id="4103249731201008433">デバイスのシリアル番号が無効です</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">署名が不適切です</translation>
<translation id="4269787794583293679">(ユーザー名なし)</translation>
<translation id="4300246636397505754">保護者からのおすすめ</translation>
-<translation id="4372948949327679948"><ph name="VALUE_TYPE"/> 値が想定されます。</translation>
+<translation id="4325863107915753736">記事が見つかりませんでした</translation>
+<translation id="4372948949327679948"><ph name="VALUE_TYPE" /> 値が想定されます。</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" /> にアクセスしようとしましたが、サーバーから提示された証明書は発行元により取り消されています。これは、サーバーから提示されたセキュリティ認証情報が信頼できないことを示しており、悪意のあるユーザーと通信しようとしている可能性があります。</translation>
+<translation id="4394049700291259645">無効にする</translation>
+<translation id="4424024547088906515">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は Chrome によって信頼されているものではありません。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
<translation id="443673843213245140">プロキシの使用は無効ですが、プロキシの設定が明示的に指定されています。</translation>
-<translation id="4506176782989081258">検証エラー: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">検証エラー: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chrome からアドレスを削除してもよろしいですか?</translation>
<translation id="4594403342090139922">削除の取り消し(&amp;U)</translation>
<translation id="4607653538520819196">データセーバーはこのページをプロキシ送信できません。</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書にはエラーがあります。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
<translation id="4726672564094551039">ポリシーを再読み込み</translation>
+<translation id="4728558894243024398">プラットフォーム</translation>
+<translation id="4771973620359291008">不明なエラーが発生しました。</translation>
<translation id="4800132727771399293">有効期限と CVC を確認してからもう一度お試しください</translation>
<translation id="4813512666221746211">ネットワーク エラー</translation>
+<translation id="4816492930507672669">ページサイズに合わせる</translation>
<translation id="4850886885716139402">表示</translation>
-<translation id="4923417429809017348">このページは、不明な言語から<ph name="LANGUAGE_LANGUAGE"/>に翻訳されました。</translation>
+<translation id="4923417429809017348">このページは、不明な言語から<ph name="LANGUAGE_LANGUAGE" />に翻訳されました。</translation>
<translation id="4926049483395192435">指定する必要があります。</translation>
<translation id="4968547170521245791">プロキシ不可</translation>
-<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE"/>から<ph name="TARGET_LANGUAGE"/>に翻訳しますか?</translation>
+<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE" />から<ph name="TARGET_LANGUAGE" />に翻訳しますか?</translation>
<translation id="5019198164206649151">代替ストアの状態が不適切です</translation>
<translation id="5031870354684148875">Google 翻訳について</translation>
+<translation id="5045550434625856497">パスワードが正しくありません</translation>
+<translation id="5087286274860437796">サーバーの証明書が現在有効ではありません。</translation>
<translation id="5089810972385038852">都道府県 / 州</translation>
+<translation id="5094747076828555589">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は Chromium によって信頼されているものではありません。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
<translation id="5095208057601539847">地方</translation>
<translation id="5145883236150621069">ポリシー応答内にエラー コードがあります</translation>
<translation id="5172758083709347301">マシン</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/>でない場合はこのエラーを報告する</translation>
+<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" />でない場合はこのエラーを報告する</translation>
<translation id="5190835502935405962">ブックマーク バー</translation>
+<translation id="5199729219167945352">試験運用機能</translation>
+<translation id="5251803541071282808">クラウド</translation>
<translation id="5295309862264981122">ナビゲーションの確認</translation>
<translation id="5299298092464848405">ポリシーの解析中にエラーが発生しました</translation>
+<translation id="5316812925700871227">反時計回りに回転</translation>
<translation id="5317780077021120954">保存</translation>
<translation id="536296301121032821">ポリシー設定を保存できませんでした</translation>
-<translation id="5439770059721715174">「<ph name="ERROR_PATH"/>」でスキーマ確認エラー: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は現在有効ではありません。設定が不適切か、悪意のあるユーザーによって接続が妨害されている可能性があります。</translation>
+<translation id="5439770059721715174">「<ph name="ERROR_PATH" />」でスキーマ確認エラー: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">ポリシーのタイムスタンプが不適切です</translation>
<translation id="5470861586879999274">編集のやり直し(&amp;R)</translation>
<translation id="5509780412636533143">管理対象のブックマーク</translation>
<translation id="5523118979700054094">ポリシー名</translation>
<translation id="552553974213252141">テキストは正しく抽出されましたか?</translation>
<translation id="5540224163453853">リクエストされた記事が見つかりませんでした。</translation>
+<translation id="5556459405103347317">再読み込み</translation>
<translation id="5565735124758917034">有効</translation>
<translation id="560412284261940334">管理はサポートされていません</translation>
<translation id="5629630648637658800">ポリシー設定を読み込めませんでした</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">現在のユーザー</translation>
<translation id="5813119285467412249">追加のやり直し(&amp;R)</translation>
<translation id="5872918882028971132">保護者からのおすすめ</translation>
-<translation id="587701087903783706">モバイル向け画面を閉じる</translation>
<translation id="59107663811261420">この販売者に対し、この種類のカードは Google ペイメントでご利用いただけません。別のカードを選択してください。</translation>
+<translation id="5975083100439434680">縮小する</translation>
<translation id="5989320800837274978">固定プロキシ サーバーと .pac スクリプト URL のどちらも指定されていません。</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">閉じる</translation>
+<translation id="6060685159320643512">これらの試験運用版は問題が発生する可能性があるため、ご利用の際には十分ご注意ください</translation>
+<translation id="6151417162996330722">サーバー証明書の有効期限が長すぎます。</translation>
<translation id="6154808779448689242">返されたポリシー トークンは現在のトークンと一致しません</translation>
<translation id="6165508094623778733">詳しく見る</translation>
<translation id="6259156558325130047">順序変更のやり直し(&amp;R)</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> のブックマーク</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> のブックマーク</translation>
<translation id="6282194474023008486">郵便番号</translation>
<translation id="6337534724793800597">ポリシーを名前でフィルタ</translation>
+<translation id="6387478394221739770">Chrome の新しい機能に関心をお持ちでしたら、chrome.com/beta から Beta チャンネルをお試しください。</translation>
+<translation id="6426993025560594914">すべての試験運用中機能がお使いのプラットフォームで使用可能です。</translation>
<translation id="6445051938772793705">国</translation>
<translation id="6458467102616083041">ポリシーによってデフォルトの検索が無効にされているため無視されます。</translation>
<translation id="647261751007945333">デバイス ポリシー</translation>
<translation id="6512448926095770873">このページを離れる</translation>
<translation id="6529602333819889595">削除のやり直し(&amp;R)</translation>
<translation id="6550675742724504774">オプション</translation>
-<translation id="6597614308054261376"><ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> にアクセスしようとしています。データセーバーは現在、このページをプロキシ送信できません。</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> 検索</translation>
+<translation id="6597614308054261376"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> にアクセスしようとしています。データセーバーは現在、このページをプロキシ送信できません。</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> 検索</translation>
<translation id="6644283850729428850">このポリシーは廃止されました。</translation>
<translation id="6646897916597483132">カードの表側に記載されている 4 桁の CVC を入力します</translation>
+<translation id="674375294223700098">不明なサーバー証明書エラー</translation>
<translation id="6753269504797312559">ポリシーの値</translation>
<translation id="6831043979455480757">翻訳</translation>
<translation id="6839929833149231406">地域</translation>
<translation id="6874604403660855544">追加のやり直し(&amp;R)</translation>
<translation id="6891596781022320156">ポリシーレベルがサポートされていません。</translation>
<translation id="6915804003454593391">ユーザー:</translation>
+<translation id="6957887021205513506">サーバーの証明書が偽造されたもののようです。</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6965978654500191972">デバイス</translation>
<translation id="6970216967273061347">地区</translation>
<translation id="6973656660372572881">固定プロキシ サーバーと .pac スクリプト URL の両方が指定されています。</translation>
<translation id="6980028882292583085">JavaScript のアラート</translation>
<translation id="7012363358306927923">中国銀聯</translation>
+<translation id="7050187094878475250"><ph name="DOMAIN" /> にアクセスしようとしましたが、サーバーに提示された証明書の有効期限が長すぎて信頼性を確認できませんでした。</translation>
<translation id="7087282848513945231">郡</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/>に翻訳できませんでした。</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" />に翻訳できませんでした。</translation>
<translation id="7139724024395191329">管轄区域</translation>
+<translation id="7179921470347911571">今すぐ再起動</translation>
<translation id="7180611975245234373">更新</translation>
<translation id="7182878459783632708">ポリシーが設定されていません</translation>
-<translation id="7186367841673660872">このページは<ph name="ORIGINAL_LANGUAGE"/>から<ph name="LANGUAGE_LANGUAGE"/>に翻訳されました</translation>
+<translation id="7186367841673660872">このページは<ph name="ORIGINAL_LANGUAGE" />から<ph name="LANGUAGE_LANGUAGE" />に翻訳されました</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531"><ph name="SITE_NAME"/> で <ph name="SEARCH_TERMS"/> を検索</translation>
+<translation id="7208899522964477531"><ph name="SITE_NAME" /> で <ph name="SEARCH_TERMS" /> を検索</translation>
+<translation id="725866823122871198">パソコンの日時(<ph name="DATE_AND_TIME" />)が正しくないため、<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> へのプライベート接続を確立できません。</translation>
<translation id="7275334191706090484">管理対象のブックマーク</translation>
<translation id="7298195798382681320">推奨</translation>
<translation id="7334320624316649418">順序変更のやり直し(&amp;R)</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">Javascript</translation>
<translation id="7537536606612762813">必須</translation>
<translation id="7542995811387359312">このフォームは安全な接続を使用していないため、クレジットカードの自動入力が無効になっています。</translation>
-<translation id="7568593326407688803">これは<ph name="ORIGINAL_LANGUAGE"/>のページです。翻訳しますか?</translation>
+<translation id="7567204685887185387">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は不正に発行されたものである可能性があります。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
+<translation id="7568593326407688803">これは<ph name="ORIGINAL_LANGUAGE" />のページです。翻訳しますか?</translation>
<translation id="7569952961197462199">Chrome からクレジット カードを削除してもよろしいですか?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/>を翻訳しない</translation>
-<translation id="7610193165460212391">値(<ph name="VALUE"/>)が範囲外です。</translation>
+<translation id="7592362899630581445">サーバーの証明書が名前の制約に違反しています。</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" />を翻訳しない</translation>
+<translation id="7610193165460212391">値(<ph name="VALUE" />)が範囲外です。</translation>
+<translation id="7674629440242451245">Chrome の新しい機能に関心をお持ちでしたら、chrome.com/dev から Dev チャンネルをお試しください。</translation>
<translation id="7752995774971033316">管理されていません</translation>
+<translation id="7761701407923456692">サーバーの証明書が URL と一致しません。</translation>
<translation id="777702478322588152">都道府県</translation>
<translation id="7791543448312431591">追加</translation>
<translation id="7805768142964895445">ステータス</translation>
<translation id="7813600968533626083">Chrome から候補を削除してもよろしいですか?</translation>
<translation id="7887683347370398519">CVC を確認してからもう一度お試しください</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">サーバーの証明書が有効になっていません。</translation>
<translation id="7956713633345437162">モバイルのブックマーク</translation>
<translation id="7961015016161918242">使用しない</translation>
<translation id="7977590112176369853">&lt;検索キーワードを入力&gt;</translation>
-<translation id="7983301409776629893">常に<ph name="ORIGINAL_LANGUAGE"/>から<ph name="TARGET_LANGUAGE"/>に翻訳する</translation>
+<translation id="7983301409776629893">常に<ph name="ORIGINAL_LANGUAGE" />から<ph name="TARGET_LANGUAGE" />に翻訳する</translation>
<translation id="7988324688042446538">パソコンのブックマーク</translation>
<translation id="7995512525968007366">指定なし</translation>
-<translation id="8034522405403831421">このページの言語は<ph name="SOURCE_LANGUAGE"/>です。<ph name="TARGET_LANGUAGE"/>に翻訳しますか?</translation>
+<translation id="8003882219468422867">企業によるオーバーライド</translation>
+<translation id="8034522405403831421">このページの言語は<ph name="SOURCE_LANGUAGE" />です。<ph name="TARGET_LANGUAGE" />に翻訳しますか?</translation>
<translation id="8088680233425245692">記事を表示できませんでした。</translation>
<translation id="8091372947890762290">サーバーで有効化が保留になっています</translation>
<translation id="8194797478851900357">移動の取り消し(&amp;U)</translation>
-<translation id="8201077131113104583">ID「<ph name="EXTENSION_ID"/>」の拡張機能に対する無効な更新 URL です。</translation>
+<translation id="8201077131113104583">ID「<ph name="EXTENSION_ID" />」の拡張機能に対する無効な更新 URL です。</translation>
<translation id="8208216423136871611">保存しない</translation>
<translation id="8218327578424803826">割り当てられた場所:</translation>
<translation id="8249320324621329438">前回の取得:</translation>
+<translation id="8294431847097064396">ソース</translation>
<translation id="8308427013383895095">ネットワーク接続に問題があったため翻訳できませんでした。</translation>
<translation id="8311778656528046050">このページを再読み込みしてもよろしいですか?</translation>
<translation id="8349305172487531364">ブックマーク バー</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">適用先</translation>
<translation id="8530504477309582336">この種類のカードは Google ペイメントでご利用いただけません。別のカードを選択してください。</translation>
<translation id="8553075262323480129">ページの言語を検出できないため翻訳できません。</translation>
-<translation id="8571890674111243710">ページを<ph name="LANGUAGE"/>に翻訳しています...</translation>
+<translation id="8559762987265718583">デバイスの日時(<ph name="DATE_AND_TIME" />)が正しくないため、<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> へのプライベート接続を確立できません。</translation>
+<translation id="8571890674111243710">ページを<ph name="LANGUAGE" />に翻訳しています...</translation>
+<translation id="8647750283161643317">すべてデフォルトに戻す</translation>
<translation id="8713130696108419660">無効なイニシャル署名です</translation>
<translation id="8725066075913043281">やり直し</translation>
+<translation id="8738058698779197622">安全な接続を確立するには時計が正しく設定されている必要があります。この理由は、本物のウェブサイトであることを示すためにウェブサイトで使用される証明書には、有効期間(発効日時と失効日時)が設定されているためです。デバイスの時計が正しくないため、Chromium ではこれらの証明書を確認できません。</translation>
<translation id="8790007591277257123">削除のやり直し(&amp;R)</translation>
<translation id="8804164990146287819">プライバシー ポリシー</translation>
+<translation id="8820817407110198400">ブックマーク</translation>
<translation id="8824019021993735287">現在、Chrome でカードを確認できません。しばらくしてからもう一度お試しください。</translation>
<translation id="8834246243508017242">連絡先からの自動入力を有効にする...</translation>
<translation id="883848425547221593">その他のブックマーク</translation>
+<translation id="884923133447025588">取り消し機構が見つかりません。</translation>
<translation id="8866481888320382733">ポリシー設定の解析中にエラーが発生しました</translation>
<translation id="8876793034577346603">ネットワーク設定を解析できませんでした。</translation>
<translation id="8891727572606052622">プロキシ モードが無効です。</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/> コマンドを実行: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">この試験運用機能は、お使いのプラットフォームでは利用できません。</translation>
+<translation id="8903921497873541725">拡大する</translation>
+<translation id="8932102934695377596">時計が遅れています</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" /> コマンドを実行: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">サーバーの証明書の有効期限が切れています。</translation>
<translation id="8988760548304185580">カードの裏面に記載されている有効期限と 3 桁の CVC を入力します</translation>
-<translation id="9020542370529661692">このページは<ph name="TARGET_LANGUAGE"/>に翻訳されています</translation>
+<translation id="901974403500617787">システム全体に適用されるフラグは所有者(<ph name="OWNER_EMAIL" />)のみが設定できます。</translation>
+<translation id="9020542370529661692">このページは<ph name="TARGET_LANGUAGE" />に翻訳されています</translation>
+<translation id="9049981332609050619"><ph name="DOMAIN" /> にアクセスしようとしましたが、サーバーから無効な証明書が提示されました。</translation>
<translation id="9125941078353557812">カードの裏面に記載されている 3 桁の CVC を入力します</translation>
<translation id="9137013805542155359">原文のページを表示</translation>
<translation id="9148507642005240123">編集の取り消し(&amp;U)</translation>
<translation id="9154176715500758432">このページにとどまる</translation>
<translation id="9170848237812810038">取消(&amp;U)</translation>
+<translation id="917450738466192189">サーバーの証明書が無効です。</translation>
+<translation id="9187827965378254003">現在のところ使用できる試験運用機能はありません。</translation>
<translation id="9207861905230894330">記事を追加できませんでした。</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">フォームをクリア</translation>
+<translation id="988159990683914416">Developer Build</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_kn.xtb b/chromium/components/strings/components_strings_kn.xtb
index 370119bfae8..c811c5b619d 100644
--- a/chromium/components/strings/components_strings_kn.xtb
+++ b/chromium/components/strings/components_strings_kn.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="kn">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="kn">
+<translation id="1032854598605920125">ಪ್ರದಕ್ಷಿಣಾಕಾರದಲ್ಲಿ ತಿರುಗಿಸು</translation>
<translation id="1055184225775184556">&amp;ಸೇರಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
<translation id="106701514854093668">ಡೆಸ್ಕ್‌ಟಾಪ್ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
-<translation id="1103523840287552314">ಯಾವಾಗಲೂ ಅನುವಾದಿಸಿ <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">ಅಗಲಕ್ಕೆ ಹೊಂದಿಸಿ</translation>
+<translation id="1103523840287552314">ಯಾವಾಗಲೂ ಅನುವಾದಿಸಿ <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;ಮರುಕ್ರಮಗೊಳಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
<translation id="111844081046043029">ನೀವು ಈ ಪುಟವನ್ನು ನಿರ್ಗಮಿಸಲು ಖಚಿತವಾಗಿ ನಿರ್ಧರಿಸಿರುವಿರಾ?</translation>
<translation id="112840717907525620">ನೀತಿಯ ಸಂಗ್ರಹ ಸರಿಯಾಗಿದೆ</translation>
<translation id="1132774398110320017">Chrome ಸ್ವಯಂತುಂಬುವಿಕೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳು...</translation>
-<translation id="1152921474424827756"><ph name="URL"/> ನ <ph name="BEGIN_LINK"/>ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಕಲನ್ನು<ph name="END_LINK"/> ಪ್ರವೇಶಿಸಿ</translation>
+<translation id="1150979032973867961">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು ನಿಮ್ಮ ಸಾಧನದ ಆಪರೇಟಿಂಗ್ ಸಿಸ್ಟಮ್‌ ಪ್ರಕಾರ ವಿಶ್ವಾಸಾರ್ಹವಾಗಿಲ್ಲ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
+<translation id="1152921474424827756"><ph name="URL" /> ನ <ph name="BEGIN_LINK" />ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಕಲನ್ನು<ph name="END_LINK" /> ಪ್ರವೇಶಿಸಿ</translation>
+<translation id="121201262018556460">ನೀವು <ph name="DOMAIN" /> ಅನ್ನು ತಲುಪಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ, ಆದರೆ ದುರ್ಬಲ ಕೀಲಿಯನ್ನು ಹೊಂದಿರುವ ಸರ್ವರ್ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಒದಗಿಸಿದೆ. ಆಕ್ರಮಣಕಾರರು ಖಾಸಗಿ ಕೀಲಿಯನ್ನು ಮುರಿದುಹಾಕಿರಬಹುದು, ಮತ್ತು ನೀವು ನಿರೀಕ್ಷಿಸಿದ ಸರ್ವರ್ ಅದಾಗಿರದೇ ಇರಬಹುದು. (ನೀವು ದಾಳಿಕೋರರೊಂದಿಗೆ ಸಂವಹನ ಮಾಡುತ್ತಿರಬಹುದು)</translation>
<translation id="1227224963052638717">ಅಜ್ಞಾತ ನೀತಿ.</translation>
<translation id="1227633850867390598">ಮೌಲ್ಯವನ್ನು ಮರೆಮಾಡಿ</translation>
<translation id="1228893227497259893">ತಪ್ಪಾದ ಅಸ್ತಿತ್ವದ ಗುರುತು</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">ಡೊಮೇನ್ ದಾಖಲಾತಿ:</translation>
<translation id="1344588688991793829">Chromium ಸ್ವಯಂತುಂಬುವಿಕೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳು...</translation>
<translation id="1426410128494586442">ಹೌದು</translation>
+<translation id="1430915738399379752">ಮುದ್ರಿಸು</translation>
<translation id="1455235771979731432">ನಿಮ್ಮ ಕಾರ್ಡ್ ಅನ್ನು ಪರಿಶೀಲಿಸುವಲ್ಲಿ ಸಮಸ್ಯೆ ಇದೆ. ನಿಮ್ಮ ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವನ್ನು ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</translation>
<translation id="1491151370853475546">ಪುಟ ಮರುಲೋಡ್ ಮಾಡು</translation>
<translation id="1549470594296187301">ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಬಳಸಲು JavaScript ಸಕ್ರಿಯಗೊಳಿಸಬೇಕು.</translation>
-<translation id="1639239467298939599">ಲೋಡ್ ಆಗುತ್ತಿದೆ</translation>
<translation id="1640180200866533862">ಬಳಕೆದಾರನ ನೀತಿಗಳು</translation>
<translation id="1644184664548287040">ನೆಟ್‌ವರ್ಕ್ ಕಾನ್ಫಿಗರೇಶನ್‌ ಅಮಾನ್ಯವಾಗಿದೆ ಹಾಗೂ ಆಮದು ಮಾಡಲಾಗುವುದಿಲ್ಲ.</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> ರಲ್ಲಿರುವ ಪುಟವು ಹೀಗೆ ಹೇಳುತ್ತದೆ:</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="168841957122794586">ಸರ್ವರ್ ಪ್ರಮಾಣಪತ್ರವು ದುರ್ಬಲ ಕ್ರಿಪ್ಟೋಗ್ರಾಫಿಕ್ ಕೀಯನ್ನು ಹೊಂದಿದೆ.</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> ರಲ್ಲಿರುವ ಪುಟವು ಹೀಗೆ ಹೇಳುತ್ತದೆ:</translation>
+<translation id="1706954506755087368">{1,plural, =1{ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ; ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರ ಬಹುಶಃ ನಾಳೆಯಿಂದ ಕಾರ್ಯನಿರ್ವಹಿಸಬಹುದು. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.}one{ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರ ಬಹುಶಃ ಭವಿಷ್ಯದಲ್ಲಿ # ದಿನಗಳಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸಬಹುದು. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.}other{ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರ ಬಹುಶಃ ಭವಿಷ್ಯದಲ್ಲಿ # ದಿನಗಳಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸಬಹುದು. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು ನಿಮ್ಮ ಸಾಧನದ ಆಪರೇಟಿಂಗ್ ಸಿಸ್ಟಮ್‌ ಪ್ರಕಾರ ವಿಶ್ವಾಸಾರ್ಹವಾಗಿಲ್ಲ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
<translation id="1821930232296380041">ಅಮಾನ್ಯವಾದ ವಿನಂತಿ ಅಥವಾ ವಿನಂತಿ ಪ್ಯಾರಾಮೀಟರ್‌ಗಳು</translation>
-<translation id="1853748787962613237">ಲೇಖನವನ್ನು ಪ್ರದರ್ಶಿಸಲು ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="1871208020102129563">.pac ಸ್ಕ್ರಿಪ್ಟ್ URL ಅಲ್ಲದೆ, ನಿಗಧಿತ ಪ್ರಾಕ್ಸಿ ಸರ್ವರ್‌ಗಳನ್ನು ಬಳಸಲು ಪ್ರಾಕ್ಸಿಯನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ.</translation>
-<translation id="1875753206475436906">ಹ್ಯೂರಿಸ್ಟಿಕ್ ಪ್ರಕಾರ: <ph name="HEURISTIC_TYPE"/>
- ಸರ್ವರ್ ವಿಧಾನ: <ph name="SERVER_TYPE"/>
- ಕ್ಷೇತ್ರ ಸಹಿ: <ph name="FIELD_SIGNATURE"/>
- ಫಾರ್ಮ್ ಸಹಿ: <ph name="FORM_SIGNATURE"/>
- ಪ್ರಾಯೋಗಿಕ ಐಡಿ: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158"><ph name="LINK"/> ಗೆ ಹೋಗಿ</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
+<translation id="194030505837763158"><ph name="LINK" /> ಗೆ ಹೋಗಿ</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="1973335181906896915">ಅನುಕ್ರಮಗೊಳಿಸುವಿಕೆಯ ದೋಷ</translation>
+<translation id="1974060860693918893">ಸುಧಾರಿತ</translation>
<translation id="2025186561304664664">ಪ್ರಾಕ್ಸಿಯನ್ನು ಸ್ವಯಂ ಕಾನ್ಫಿಗರ್ ಆಗಿ ಹೊಂದಿಸಲಾಗಿದೆ.</translation>
<translation id="2025623846716345241">ಮರುಲೋಡ್ ದೃಢೀಕರಿಸಿ</translation>
-<translation id="2030481566774242610">ನಿಮ್ಮ ಮಾತಿನ ಅರ್ಥ <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">ನಿಮ್ಮ ಮಾತಿನ ಅರ್ಥ <ph name="LINK" />?</translation>
<translation id="2053553514270667976">ಪಿನ್ ಕೋಡ್</translation>
<translation id="20817612488360358">ಸಿಸ್ಟಂ ಪ್ರಾಕ್ಸಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬಳಸಲು ಹೊಂದಿಸಲಾಗಿದೆ ಆದರೆ ಬಹಿರಂಗವಾದ ಪ್ರಾಕ್ಸಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಸಹ ನಿರ್ದಿಷ್ಟಪಡಿಸಲಾಗಿದೆ.</translation>
<translation id="2094505752054353250">ಡೊಮೇನ್ ಹೊಂದುತ್ತಿಲ್ಲ</translation>
<translation id="2096368010154057602">ವಿಭಾಗ</translation>
<translation id="2113977810652731515">ಕಾರ್ಡ್</translation>
-<translation id="2114841414352855701"><ph name="POLICY_NAME"/> ರಿಂದ ಅತಿಕ್ರಮಿಸಲಾಗಿರುವ ಕಾರಣ ಇದನ್ನು ನಿರ್ಲಕ್ಷಿಸಲಾಗಿದೆ.</translation>
+<translation id="2114841414352855701"><ph name="POLICY_NAME" /> ರಿಂದ ಅತಿಕ್ರಮಿಸಲಾಗಿರುವ ಕಾರಣ ಇದನ್ನು ನಿರ್ಲಕ್ಷಿಸಲಾಗಿದೆ.</translation>
+<translation id="2128531968068887769">ಸ್ಥಳೀಯ ಗ್ರಾಹಕ</translation>
<translation id="213826338245044447">ಮೊಬೈಲ್ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
+<translation id="2171101176734966184">ನೀವು <ph name="DOMAIN" /> ಅನ್ನು ತಲುಪಲು ಪ್ರಯತ್ನಿಸಿದಿರಿ, ಆದರೆ ದುರ್ಬಲ ಸಹಿ ಅಲ್ಗಾರಿದಮ್ ಬಳಸಿಕೊಂಡು ಸಹಿ ಮಾಡಿದ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಸರ್ವರ್ ಒದಗಿಸಿದೆ. ಇದರರ್ಥ ಸರ್ವರ್ ಒದಗಿಸಿದ ಸುರಕ್ಷತೆ ಪ್ರಮಾಣಪತ್ರಗಳನ್ನು ಖೋಟಾ ತಯಾರಿಸಿರಬಹುದು, ಮತ್ತು ನೀವು ನಿರೀಕ್ಷಿಸಿದ ಸರ್ವರ್ ಅದಾಗಿರದೇ ಇರಬಹುದು (ನೀವು ದಾಳಿಕೋರರೊಂದಿಗೆ ಸಂವಹನ ಮಾಡುತ್ತಿರಬಹುದು).</translation>
<translation id="2181821976797666341">ನಿಯಮಗಳು</translation>
<translation id="2212735316055980242">ನೀತಿ ಕಂಡು ಬಂದಿಲ್ಲ</translation>
<translation id="2213606439339815911">ನಮೂದುಗಳನ್ನು ಪಡೆಯಲಾಗುತ್ತಿದೆ...</translation>
<translation id="225207911366869382">ಈ ನೀತಿಗಾಗಿ ಈ ಮೌಲ್ಯವನ್ನು ಅಸಮ್ಮತಿಸಲಾಗಿದೆ.</translation>
<translation id="2262243747453050782">HTTP ದೋಷ</translation>
-<translation id="2270192940992995399">ಲೇಖನವನ್ನು ಹುಡುಕಲು ವಿಫಲವಾಗಿದೆ.</translation>
-<translation id="2328300916057834155">ಸೂಚ್ಯಂಕದಲ್ಲಿ <ph name="ENTRY_INDEX"/> ನಿರ್ಲಕ್ಷಿಸಲಾದ ಅಮಾನ್ಯ ಬುಕ್‌ಮಾರ್ಕ್‌</translation>
+<translation id="2282872951544483773">ಲಭ್ಯವಿಲ್ಲದ ಪ್ರಯೋಗಗಳು</translation>
+<translation id="229702904922032456">ಮೂಲ ಅಥವಾ ಮಧ್ಯಂತರ ಪ್ರಮಾಣಪತ್ರದ ಅವಧಿ ಮುಗಿದಿದೆ.</translation>
+<translation id="2328300916057834155">ಸೂಚ್ಯಂಕದಲ್ಲಿ <ph name="ENTRY_INDEX" /> ನಿರ್ಲಕ್ಷಿಸಲಾದ ಅಮಾನ್ಯ ಬುಕ್‌ಮಾರ್ಕ್‌</translation>
<translation id="2354001756790975382">ಇತರ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="2359808026110333948">ಮುಂದುವರಿಸು</translation>
<translation id="2367567093518048410">ಹಂತ</translation>
+<translation id="2384307209577226199">ಎಂಟರ್‌ಪ್ರೈಸ್ ಡೀಫಾಲ್ಟ್</translation>
+<translation id="2386255080630008482">ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಹಿಂಪಡೆಯಲಾಗಿದೆ.</translation>
<translation id="2392959068659972793">ಯಾವುದೇ ಮೌಲ್ಯ ಹೊಂದಿಸಿಲ್ಲದ ನೀತಿಗಳನ್ನು ತೋರಿಸಿ</translation>
<translation id="2396249848217231973">&amp;ಅಳಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸು</translation>
+<translation id="2413528052993050574">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಹಿಂತೆಗೆದುಕೊಳ್ಳಲಾಗಿರಬಹುದು. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
<translation id="2455981314101692989">ಈ ಫಾರ್ಮ್ ಅನ್ನು ಭರ್ತಿ ಮಾಡುವ ಸಲುವಾಗಿ ಈ ವೆಬ್‌ಪುಟವನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ.</translation>
<translation id="2479410451996844060">ಅಮಾನ್ಯವಾದ ಹುಡುಕಾಟ URL.</translation>
+<translation id="2491120439723279231">ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರವು ದೋಷಗಳನ್ನು ಹೊಂದಿದೆ.</translation>
<translation id="2495083838625180221">JSON ವಿಶ್ಲೇಷಕ</translation>
<translation id="2498091847651709837">ಹೊಸ ಕಾರ್ಡ್ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ</translation>
<translation id="2556876185419854533">&amp;ಸಂಪಾದಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
-<translation id="2581221116934462656">ನೀವು ಮುಂದಿನ ಬಾರಿ ಈ ಸೈಟ್‌ನಿಂದ <ph name="LANGUAGE_NAME"/> ಪುಟಗಳನ್ನು ಅನುವಾದಿಸಬೇಕೆ ಎಂದು <ph name="PRODUCT_NAME"/> ಅನ್ನು ಕೇಳಬೇಕೆಂದು ನೀವು ಬಯಸುವಿರಾ?</translation>
+<translation id="2581221116934462656">ನೀವು ಮುಂದಿನ ಬಾರಿ ಈ ಸೈಟ್‌ನಿಂದ <ph name="LANGUAGE_NAME" /> ಪುಟಗಳನ್ನು ಅನುವಾದಿಸಬೇಕೆ ಎಂದು <ph name="PRODUCT_NAME" /> ಅನ್ನು ಕೇಳಬೇಕೆಂದು ನೀವು ಬಯಸುವಿರಾ?</translation>
<translation id="2587841377698384444">ಡೈರೆಕ್ಟರಿ API ID:</translation>
<translation id="2597378329261239068">ಈ ಡಾಕ್ಯುಮೆಂಟ್‌ ಅನ್ನು ಪಾಸ್‌ವರ್ಡ್‌ನಿಂದ ರಕ್ಷಿಸಲಾಗಿದೆ. ದಯವಿಟ್ಟು ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ನಮೂದಿಸಿ.</translation>
+<translation id="2625385379895617796">ನಿಮ್ಮ ಗಡಿಯಾರವು ಮುಂದೆ ಇದೆ</translation>
<translation id="2639739919103226564">ಸ್ಥಿತಿ: </translation>
+<translation id="2653659639078652383">ಸಲ್ಲಿಸು</translation>
<translation id="2704283930420550640">ಮೌಲ್ಯವು ಸ್ವರೂಪಕ್ಕೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ.</translation>
<translation id="2721148159707890343">ವಿನಂತಿಯನ್ನು ಯಶಸ್ವಿಗೊಳಿಸಲಾಗಿದೆ</translation>
+<translation id="2728127805433021124">ಕ್ಷೀಣವಾದ ಸಹಿ ಅಲ್ಗಾರಿದಮ್ ಬಳಸಿಕೊಂಡು ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರಕ್ಕೆ ಸಹಿ ಮಾಡಲಾಗಿದೆ.</translation>
<translation id="2774256287122201187">ನೀವು ಮಂದುವರಿಸಬಹುದು. ನೀವು ಪುಟಕ್ಕೆ ಮುಂದುವರಿದರೆ, ಈ ಎಚ್ಚರಿಕೆಯು ಐದು ನಿಮಿಷಗಳ ಕಾಲ ಮತ್ತೆ ಗೋಚರಿಸುವುದಿಲ್ಲ.</translation>
<translation id="277499241957683684">ಸಾಧನದ ರೆಕಾರ್ಡ್ ಕಾಣೆಯಾಗಿದೆ</translation>
<translation id="2835170189407361413">ಫಾರ್ಮ್ ತೆರವುಗೊಳಿಸು</translation>
-<translation id="2855922900409897335">ನಿಮ್ಮ <ph name="CREDIT_CARD"/> ಪರಿಶೀಲಿಸಿ</translation>
+<translation id="2855922900409897335">ನಿಮ್ಮ <ph name="CREDIT_CARD" /> ಪರಿಶೀಲಿಸಿ</translation>
+<translation id="2915500479781995473">ಈ ಸರ್ವರ್‌‌ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರದ ಅವಧಿ ಮುಗಿದಿದೆ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು. ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನ ಗಡಿಯಾರವನ್ನು ಪ್ರಸ್ತುತ <ph name="CURRENT_TIME" /> ಗೆ ಹೊಂದಿಸಲಾಗಿದೆ. ಅದು ಸರಿಯಾಗಿ ತೋರುತ್ತಿದೆಯೆ? ಇಲ್ಲವಾದರೆ, ನಿಮ್ಮ ಸಿಸ್ಟಮ್‌ನ ಗಡಿಯಾರವನ್ನು ನೀವು ಸರಿಪಡಿಸಬೇಕು ಹಾಗೂ ನಂತರ ಈ ಪುಟವನ್ನು ರೀಫ್ರೆಶ್ ಮಾಡಿ.</translation>
+<translation id="2922350208395188000">ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಪರಿಶೀಲಿಸಲಾಗುವುದಿಲ್ಲ.</translation>
+<translation id="2941952326391522266">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು <ph name="DOMAIN2" /> ದಿಂದ ಆಗಿದೆ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
<translation id="2958431318199492670">ONC ಪ್ರಮಾಣಿತಕ್ಕೆ ನೆಟ್‌ವರ್ಕ್ ಕಾನ್ಫಿಗರೇಶನ್ ಅನುಸರಣೆಯಾಗುವುದಿಲ್ಲ. ಕಾನ್ಫಿಗರೇಶನ್‌ನ ಭಾಗಗಳನ್ನು ಆಮದು ಮಾಡಲಾಗದಿರಬಹುದು.</translation>
<translation id="2972581237482394796">&amp;ಮತ್ತೆಮಾಡು</translation>
-<translation id="3010559122411665027">ಪಟ್ಟಿ ನಮೂದು &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">ಪಟ್ಟಿ ನಮೂದು "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">ತಪ್ಪಾದ ನೀತಿಯ ಪ್ರಕಾರ</translation>
<translation id="3105172416063519923">ಸ್ವತ್ತು ID:</translation>
<translation id="3145945101586104090">ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಡೀಕೋಡ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">ದ್ವೀಪ</translation>
<translation id="3219579145727097045">ನಿಮ್ಮ ಕಾರ್ಡ್‌ನ ಮುಂಭಾಗದಲ್ಲಿರುವ ಮುಕ್ತಾಯದ ದಿನಾಂಕ ಮತ್ತು 4-ಅಂಕಿಗಳ CVC ಅನ್ನು ನಮೂದಿಸಿ</translation>
-<translation id="3228969707346345236">ಪುಟವು ಈಗಾಗಲೇ <ph name="LANGUAGE"/> ರಲ್ಲಿ ಇರುವುದರ ಕಾರಣ ಭಾಷಾಂತರವು ವಿಫಲವಾಗಿದೆ.</translation>
+<translation id="3225919329040284222">ಆಂತರಿಕ ಮಾನದಂಡಗಳಿಗೆ ಹೊಂದಿಕೆಯಾಗದ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಸರ್ವರ್ ಹಾಜರಿಪಡಿಸಿದೆ. ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ಸಲುವಾಗಿ ಕೆಲವು ಹೆಚ್ಚು ಸುರಕ್ಷಿತ ವೆಬ್ ಸೈಟ್‌ಗಳಲ್ಲಿ ಈ ಮಾನದಂಡಗಳನ್ನು ಸೇರ್ಪಡೆಗೊಳಿಸಲಾಗಿದೆ.</translation>
+<translation id="3228969707346345236">ಪುಟವು ಈಗಾಗಲೇ <ph name="LANGUAGE" /> ರಲ್ಲಿ ಇರುವುದರ ಕಾರಣ ಭಾಷಾಂತರವು ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="3270847123878663523">&amp;ಮರುಕ್ರಮಗೊಳಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸು</translation>
+<translation id="3286538390144397061">ಈಗ ಮರುಪ್ರಾರಂಭಿಸಿ</translation>
<translation id="333371639341676808">ಈ ಪುಟ ಹೆಚ್ಚುವರಿ ಸಂವಾದಗಳನ್ನು ರಚಿಸುವುದನ್ನು ತಡೆಯಿರಿ.</translation>
-<translation id="3369366829301677151">ನಿಮ್ಮ <ph name="CREDIT_CARD"/> ಅನ್ನು ನವೀಕರಿಸಿ ಮತ್ತು ಪರಿಶೀಲಿಸಿ</translation>
+<translation id="3340978935015468852">ಸೆಟ್ಟಿಂಗ್‌ಗಳು</translation>
+<translation id="3369192424181595722">ಗಡಿಯಾರ ದೋಷ</translation>
+<translation id="3369366829301677151">ನಿಮ್ಮ <ph name="CREDIT_CARD" /> ಅನ್ನು ನವೀಕರಿಸಿ ಮತ್ತು ಪರಿಶೀಲಿಸಿ</translation>
<translation id="337363190475750230">ಅನುಮತಿ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ</translation>
<translation id="3377188786107721145">ನೀತಿಯ ಪಾರ್ಸ್ ದೋಷ</translation>
<translation id="3380365263193509176">ಅಜ್ಞಾತ ದೋಷ</translation>
<translation id="3380864720620200369">ಕ್ಲೈಂಟ್ ID:</translation>
<translation id="3427342743765426898">&amp;ಸಂಪಾದಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
+<translation id="3435896845095436175">ಸಕ್ರಿಯಗೊಳಿಸು</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">ವಿರಾಮವನ್ನು ಪಡೆಯಿರಿ:</translation>
+<translation id="3462200631372590220">ಸುಧಾರಿತ ಆಯ್ಕೆಮಾಡಿ</translation>
+<translation id="3528171143076753409">ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರ ನಂಬಲರ್ಹವಾಗಿಲ್ಲ.</translation>
<translation id="3542684924769048008">ಇದಕ್ಕೆ ಪಾಸ್‌ವರ್ಡ್ ಬಳಸಿ:</translation>
<translation id="3583757800736429874">&amp;ಸರಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="3623476034248543066">ಮೌಲ್ಯವನ್ನು ತೋರಿಸಿ</translation>
+<translation id="3648607100222897006">ಈ ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯಗಳು ಯಾವುದೇ ಸಮಯದಲ್ಲಾದರೂ ಬದಲಾಗಬಹುದು, ಒಡೆಯಬಹುದು, ಅಥವಾ ಕಾಣೆಯಾಗಬಹುದು. ಒಂದು ಪ್ರಯೋಗವನ್ನು ಆನ್ ಮಾಡಿದರೆ ಏನು ಆಗಬಹುದು ಎಂಬುವುದರ ಬಗ್ಗೆ ನಾವು ಯಾವುದೇ ಖಾತ್ರಿಗಳನ್ನು ನೀಡುವುದಿಲ್ಲ, ಮತ್ತು ನಿಮ್ಮ ಬ್ರೌಸರ್ ನಿರಂತರವಾಗಿ ದಹನಕ್ಕೊಳಗಾಗಬಹುದು. ಜೋಕ್‌ಗಳು ಆ ಕಡೆ ಇರಲಿ, ನಿಮ್ಮ ಬ್ರೌಸರ್ ನಿಮ್ಮ ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸಿ ಹಾಕಬಹುದು, ಅಥವಾ ನಿಮ್ಮ ಸುರಕ್ಷಿತ ಮತ್ತು ಗೌಪ್ಯತೆಯು ಅನಿರೀಕ್ಷಿತ ರೀತಿಯಲ್ಲಿ ಧಕ್ಕೆಯುಂಟಾಗಬಹುದು. ಯಾವುದೇ ಪ್ರಯೋಗಗಳನ್ನು ನೀವು ಸಕ್ರಿಯಗೊಳಿಸಿದಲ್ಲಿ ಈ ಬ್ರೌಸರ್‌ನ ಎಲ್ಲ ಬಳಕೆದಾರರಿಗೂ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗುವುದು. ದಯವಿಟ್ಟು ಎಚ್ಚರಿಕೆಯಿಂದ ಮುಂದುವರಿಯಿರಿ.</translation>
<translation id="3650584904733503804">ಊರ್ಜಿತಗೊಳಿಸುವಿಕೆಯು ಯಶಸ್ವಿಯಾಗಿದೆ</translation>
<translation id="370665806235115550">ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ...</translation>
<translation id="3712624925041724820">ಪರವಾನಗಿಗಳು ಬರಿದಾಗಿವೆ</translation>
<translation id="3739623965217189342">ನೀವು ನಕಲಿಸಿದ ಲಿಂಕ್</translation>
<translation id="375403751935624634">ಸರ್ವರ್ ದೋಷದ ಕಾರಣ ಅನುವಾದವು ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="385051799172605136">ಹಿಂದೆ</translation>
+<translation id="3858027520442213535">ದಿನಾಂಕ ಮತ್ತು ಸಮಯವನ್ನು ನವೀಕರಿಸಿ</translation>
<translation id="3884278016824448484">ಸಂಘರ್ಷಗೊಳ್ಳುತ್ತಿರುವ ಸಾಧನ ಗುರುತಿಸುವಿಕೆ</translation>
<translation id="3885155851504623709">ಪಾರಿಷ್</translation>
<translation id="3934680773876859118">PDF ಡಾಕ್ಯುಮೆಂಟ್ ಅನ್ನು ಲೋಡ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ</translation>
<translation id="3963721102035795474">ರೀಡರ್‌ ಮೋಡ್‌</translation>
<translation id="4030383055268325496">&amp;ಸೇರಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
-<translation id="4058922952496707368">ಕೀ &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ಎಚ್ಚರಿಕೆ</translation>
+<translation id="4058922952496707368">ಕೀ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">ಪ್ರಾಕ್ಸಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು .pac ಸ್ಕ್ರಿಪ್ಟ್ URL ಬಳಸುವಂತೆ ಹೊಂದಿಸಲಾಗಿದೆ, ಹೊಂದಿಸಿದ ಪ್ರಾಕ್ಸಿ ಸರ್ವರ್‌ಗಳಲ್ಲ.</translation>
<translation id="409504436206021213">ಮರುಲೋಡ್ ಮಾಡಬೇಡ</translation>
<translation id="4103249731201008433">ಸಾಧನದ ಸರಣಿಯ ಸಂಖ್ಯೆ ಅಮಾನ್ಯವಾಗಿದೆ</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">ತಪ್ಪಾದ ಸಹಿ</translation>
<translation id="4269787794583293679">(ಯಾವುದು ಬಳಕೆದಾರಹೆಸರಿಲ್ಲ)</translation>
<translation id="4300246636397505754">ಪೋಷಕ ಸಲಹೆಗಳು</translation>
-<translation id="4372948949327679948">ನಿರೀಕ್ಷಿತ <ph name="VALUE_TYPE"/> ಮೌಲ್ಯ.</translation>
+<translation id="4325863107915753736">ಲೇಖನ ಕಂಡುಬರಲಿಲ್ಲ</translation>
+<translation id="4372948949327679948">ನಿರೀಕ್ಷಿತ <ph name="VALUE_TYPE" /> ಮೌಲ್ಯ.</translation>
+<translation id="4377125064752653719">ನೀವು <ph name="DOMAIN" /> ಅನ್ನು ತಲುಪಲು ಪ್ರಯತ್ನಿಸಿದಿರಿ, ಆದರೆ ಸರ್ವರ್ ನೀಡಿದ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಅದರ ನೀಡುವವರು ಹಿಂತೆಗೆದುಕೊಂಡಿದ್ದಾರೆ. ಇದರರ್ಥ ಸರ್ವರ್ ನೀಡಿದ ಸುರಕ್ಷತೆ ರುಜುವಾತುಗಳನ್ನು ಖಂಡಿತವಾಗಿ ನಂಬಲಾಗುವುದಿಲ್ಲ. ನೀವು ಆಕ್ರಮಣಕಾರರೊಂದಿಗೆ ಸಂವಹಿಸುತ್ತಿರಬಹುದು.</translation>
+<translation id="4394049700291259645">ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ</translation>
+<translation id="4424024547088906515">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು Chrome ಪಾಲಿಗೆ ವಿಶ್ವಾಸಾರ್ಹವಾಗಿಲ್ಲ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
<translation id="443673843213245140">ಪ್ರಾಕ್ಸಿಯ ಬಳಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ ಆದರೆ ಬಹಿರಂಗ ಪ್ರಾಕ್ಸಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಲಾಗಿದೆ.</translation>
-<translation id="4506176782989081258">ಮೌಲ್ಯೀಕರಿಸುವಿಕೆಯ ದೋಷ: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">ಮೌಲ್ಯೀಕರಿಸುವಿಕೆಯ ದೋಷ: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chrome ನಿಂದ ವಿಳಾಸವನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?</translation>
<translation id="4594403342090139922">&amp;ಅಳಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
<translation id="4607653538520819196">ಈ ಪುಟವನ್ನು ಡೇಟಾ ಉಳಿಸುವಿಕೆಯಿಂದ ಪ್ರಾಕ್ಸಿ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರದಲ್ಲಿ ಸಾಕಷ್ಟು ದೋಷಗಳಿವೆ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
<translation id="4726672564094551039">ನೀತಿಗಳನ್ನು ಮರುಲೋಡ್ ಮಾಡಿ</translation>
+<translation id="4728558894243024398">ಪ್ಲಾಟ್‌ಫಾರ್ಮ್</translation>
+<translation id="4771973620359291008">ಅಜ್ಞಾತ ದೋಷವೊಂದು ಎದುರಾಗಿದೆ.</translation>
<translation id="4800132727771399293">ನಿಮ್ಮ ಮುಕ್ತಾಯದ ದಿನಾಂಕ ಮತ್ತು CVC ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ</translation>
<translation id="4813512666221746211">ನೆಟ್‌ವರ್ಕ್ ದೋಷ</translation>
+<translation id="4816492930507672669">ಪುಟಕ್ಕೆ ಹೊಂದಿಸು</translation>
<translation id="4850886885716139402">ವೀಕ್ಷಣೆ</translation>
-<translation id="4923417429809017348">ಗೊತ್ತಿಲ್ಲದ ಭಾಷೆಯಿಂದ <ph name="LANGUAGE_LANGUAGE"/> ಗೆ ಈ ಪುಟವನ್ನು ಭಾಷಾಂತರಿಸಲಾಗಿದೆ</translation>
+<translation id="4923417429809017348">ಗೊತ್ತಿಲ್ಲದ ಭಾಷೆಯಿಂದ <ph name="LANGUAGE_LANGUAGE" /> ಗೆ ಈ ಪುಟವನ್ನು ಭಾಷಾಂತರಿಸಲಾಗಿದೆ</translation>
<translation id="4926049483395192435">ನಿರ್ದಿಷ್ಟಪಡಿಸಬೇಕಾಗಿದೆ.</translation>
<translation id="4968547170521245791">ಪ್ರಾಕ್ಸಿ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ</translation>
-<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE"/> ರಿಂದ <ph name="TARGET_LANGUAGE"/> ಗೆ ಅನುವಾದಿಸಬೇಕೇ?</translation>
+<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE" /> ರಿಂದ <ph name="TARGET_LANGUAGE" /> ಗೆ ಅನುವಾದಿಸಬೇಕೇ?</translation>
<translation id="5019198164206649151">ಕಳಪೆ ಸ್ಥಿತಿಯಲ್ಲಿ ಸಂಗ್ರಹಣೆಯನ್ನು ಹಿಂತಿರುಗಿಸಲಾಗಿದೆ</translation>
<translation id="5031870354684148875">Google ಅನುವಾದದ ಕುರಿತು</translation>
+<translation id="5045550434625856497">ತಪ್ಪಾದ ಪಾಸ್‌ವರ್ಡ್</translation>
+<translation id="5087286274860437796">ಈ ಸಮಯದಲ್ಲಿ ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರ ಮಾನ್ಯವಾಗಿಲ್ಲ.</translation>
<translation id="5089810972385038852">ರಾಜ್ಯ</translation>
+<translation id="5094747076828555589">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು Chromium ಮೂಲಕ ವಿಶ್ವಾಸಾರ್ಹವಾಗಿಲ್ಲ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
<translation id="5095208057601539847">ಪ್ರಾಂತ್ಯ</translation>
<translation id="5145883236150621069">ನೀತಿ ಪ್ರತಿಕ್ರಿಯೆಯಲ್ಲಿ ದೋಷದ ಕೋಡ್ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ</translation>
<translation id="5172758083709347301">ಯಂತ್ರ</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/> ರಲ್ಲಿ ಇಲ್ಲವೆ? ಈ ದೋಷವನ್ನು ವರದಿ ಮಾಡಿ</translation>
+<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> ರಲ್ಲಿ ಇಲ್ಲವೆ? ಈ ದೋಷವನ್ನು ವರದಿ ಮಾಡಿ</translation>
<translation id="5190835502935405962">ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳ ಬಾರ್</translation>
+<translation id="5199729219167945352">ಪ್ರಯೋಗಗಳು</translation>
+<translation id="5251803541071282808">ಮೇಘ</translation>
<translation id="5295309862264981122">ನ್ಯಾವಿಗೇಶನ್ ಅನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ</translation>
<translation id="5299298092464848405">ನೀತಿಯ ಪಾರ್ಸಿಂಗ್‌ನಲ್ಲಿ ದೋಷ</translation>
+<translation id="5316812925700871227">ಅಪ್ರದಕ್ಷಿಣವಾಗಿ ತಿರುಗಿಸು</translation>
<translation id="5317780077021120954">ಉಳಿಸು</translation>
<translation id="536296301121032821">ನೀತಿಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಸಂಗ್ರಹಿಸುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ</translation>
-<translation id="5439770059721715174">&quot;<ph name="ERROR_PATH"/>&quot; ನಲ್ಲಿ ಸ್ಕೀಮಾ ಮೌಲ್ವೀಕರಣ ದೋಷ: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಈ ಸಮಯದಲ್ಲಿ ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು ಮಾನ್ಯವಾಗಿಲ್ಲ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
+<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" ನಲ್ಲಿ ಸ್ಕೀಮಾ ಮೌಲ್ವೀಕರಣ ದೋಷ: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">ತಪ್ಪಾದ ನೀತಿಯ ಸಮಯಸ್ಟ್ಯಾಂಪ್</translation>
<translation id="5470861586879999274">&amp;ಸಂಪಾದಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="5509780412636533143">ನಿರ್ವಹಿಸಿದ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="5523118979700054094">ನೀತಿ ಹೆಸರು</translation>
<translation id="552553974213252141">ಪಠ್ಯವನ್ನು ಸರಿಯಾಗಿ ಪ್ರತ್ಯೇಕಿಸಲಾಗಿದೆಯೇ?</translation>
<translation id="5540224163453853">ವಿನಂತಿಸಿದ ಲೇಖನವನ್ನು ಹುಡುಕಲು ಸಾಧವಾಗಲಿಲ್ಲ.</translation>
+<translation id="5556459405103347317">ಮರುಲೋಡ್‌</translation>
<translation id="5565735124758917034">ಸಕ್ರಿಯ</translation>
<translation id="560412284261940334">ನಿರ್ವಾಹಕ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ</translation>
<translation id="5629630648637658800">ನೀತಿಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">ಪ್ರಸ್ತುತ ಬಳಕೆದಾರ</translation>
<translation id="5813119285467412249">&amp;ಸೇರಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="5872918882028971132">ಪೋಷಕ ಸಲಹೆಗಳು</translation>
-<translation id="587701087903783706">ಮೊಬೈಲ್-ಸ್ನೇಹಿ ವೀಕ್ಷಣೆ ಮುಚ್ಚಿ</translation>
<translation id="59107663811261420">ಈ ವರ್ತಕರಿಗೆ Google Payments ನಿಂದ ಈ ಪ್ರಕಾರದ ಕಾರ್ಡ್ ಬೆಂಬಲಿತವಾಗಿಲ್ಲ. ದಯವಿಟ್ಟು ಬೇರೆಯ ಕಾರ್ಡ್ ಆಯ್ಕೆಮಾಡಿ.</translation>
+<translation id="5975083100439434680">ಜೂಮ್ ಔಟ್</translation>
<translation id="5989320800837274978">ಹೊಂದಿಸಿದ ಪ್ರಾಕ್ಸಿ ಸರ್ವರ್‌ಗಳು ಆಗಲಿ ಅಥವಾ .pac ಸ್ಕ್ರಿಪ್ಟ್ URL ಅನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಿಲ್ಲ.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">ಮುಚ್ಚು</translation>
+<translation id="6060685159320643512">ಜಾಗ್ರತೆ, ಈ ಪ್ರಯೋಗಗಳು ವಿಫಲವಾಗಬಹುದು</translation>
+<translation id="6151417162996330722">ಸರ್ವರ್ ಪ್ರಮಾಣಪತ್ರವು ತುಂಬಾ ಉದ್ದವಾದ ವಾಯಿದೆ ಅವಧಿಯನ್ನು ಹೊಂದಿದೆ.</translation>
<translation id="6154808779448689242">ಹಿಂತಿರುಗಿಸಲಾದ ನೀತಿಯ ಟೋಕನ್‌ಗೆ ಪ್ರಸ್ತುತ ಟೋಕನ್ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ</translation>
<translation id="6165508094623778733">ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ</translation>
<translation id="6259156558325130047">&amp;ಮರುಕ್ರಮಗೊಳಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="6282194474023008486">ಪೋಸ್ಟಲ್ ಕೋಡ್</translation>
<translation id="6337534724793800597">ಹೆಸರಿನ ಪ್ರಕಾರವಾಗಿ ನೀತಿಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ</translation>
+<translation id="6387478394221739770">ಉತ್ತಮವಾದ ಹೊಸ Chrome ವೈಶಿಷ್ಟ್ಯಗಳಲ್ಲಿ ಆಸಕ್ತಿ ಇದೆಯೇ? chrome.com/beta ನಲ್ಲಿ ನಮ್ಮ ಬೀಟಾ ಚಾನಲ್ ಪ್ರಯತ್ನಿಸಿ.</translation>
+<translation id="6426993025560594914">ಎಲ್ಲಾ ಪ್ರಯೋಗಗಳು ನಿಮ್ಮ ಫ್ಲಾಟ್‌ಫಾರ್ಮ್‌ನಲ್ಲಿ ಲಭ್ಯವಿದೆ!</translation>
<translation id="6445051938772793705">ರಾಷ್ಟ್ರ</translation>
<translation id="6458467102616083041">ಡೀಫಾಲ್ಟ್ ಹುಡುಕಾಟವನ್ನು ನೀತಿಯಿಂದ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿರುವುದರಿಂದ ನಿರ್ಲಕ್ಷಿಸಲಾಗಿದೆ.</translation>
<translation id="647261751007945333">ಸಾಧನ ನೀತಿಗಳು</translation>
<translation id="6512448926095770873">ಈ ಪುಟವನ್ನು ತ್ಯಜಿಸಿ</translation>
<translation id="6529602333819889595">&amp;ಅಳಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="6550675742724504774">ಆಯ್ಕೆಗಳು</translation>
-<translation id="6597614308054261376"><ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> ಅನ್ನು ತಲುಪಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರುವಿರಿ. ಈ ಪುಟವನ್ನು ಈ ಸಮಯದಲ್ಲಿ ಡೇಟಾ ಉಳಿಸುವಿಕೆಯಿಂದ ಪ್ರಾಕ್ಸಿ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> ಹುಡುಕಾಟ</translation>
+<translation id="6597614308054261376"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ಅನ್ನು ತಲುಪಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರುವಿರಿ. ಈ ಪುಟವನ್ನು ಈ ಸಮಯದಲ್ಲಿ ಡೇಟಾ ಉಳಿಸುವಿಕೆಯಿಂದ ಪ್ರಾಕ್ಸಿ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> ಹುಡುಕಾಟ</translation>
<translation id="6644283850729428850">ಈ ನೀತಿಯನ್ನು ವಿನಂತಿಸಲಾಗಿದೆ.</translation>
<translation id="6646897916597483132">ನಿಮ್ಮ ಕಾರ್ಡ್ ಮುಂಭಾಗದಲ್ಲಿರುವ 4-ಅಂಕಿ CVC ಅನ್ನು ನಮೂದಿಸಿ</translation>
+<translation id="674375294223700098">ಅಜ್ಞಾತ ಸರ್ವರ್ ಪ್ರಮಾಣಪತ್ರ ದೋಷ.</translation>
<translation id="6753269504797312559">ನೀತಿ ಮೌಲ್ಯ</translation>
<translation id="6831043979455480757">ಅನುವಾದಿಸು</translation>
<translation id="6839929833149231406">ಪ್ರದೇಶ</translation>
<translation id="6874604403660855544">&amp;ಸೇರಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="6891596781022320156">ನೀತಿಯ ಮಟ್ಟವು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ.</translation>
<translation id="6915804003454593391">ಬಳಕೆದಾರ:</translation>
+<translation id="6957887021205513506">ಸರ್ವರ್‌ಗಳ ಪ್ರಮಾಣಪತ್ರವು ನಕಲಿಯಾಗಿ ಗೋಚರಿಸುತ್ತದೆ.</translation>
<translation id="6965382102122355670">ಸರಿ</translation>
<translation id="6965978654500191972">ಸಾಧನ</translation>
<translation id="6970216967273061347">ಜಿಲ್ಲೆ</translation>
<translation id="6973656660372572881">ಹೊಂದಿಸಿದ ಪ್ರಾಕ್ಸಿ ಸರ್ವರ್‌ಗಳು ಮತ್ತು .pac ಸ್ಕ್ರಿಪ್ಟ್ URL ಎರಡನ್ನೂ ನಿರ್ದಿಷ್ಟಪಡಿಸಲಾಗಿದೆ.</translation>
<translation id="6980028882292583085">Javascript ಎಚ್ಚರಿಕೆ</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">ನೀವು <ph name="DOMAIN" /> ಅನ್ನು ತಲುಪಲು ಪ್ರಯತ್ನಿಸಿರುವಿರಿ, ಆದರೆ ಸರ್ವರ್ ವಿಶ್ವಾಸಾರ್ಹವಾಗಿರಲು ತುಂಬ ಉದ್ದವಾದ ವಾಯಿದೆ ಅವಧಿಯನ್ನು ಹೊಂದಿರುವ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಸಲ್ಲಿಸಿದೆ.</translation>
<translation id="7087282848513945231">ರಾಷ್ಟ್ರ</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/> ಗೆ ಅನುವಾದ ವಿಫಲವಾಗಿದೆ.</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" /> ಗೆ ಅನುವಾದ ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="7139724024395191329">ಎಮಿರೇಟ್</translation>
+<translation id="7179921470347911571">ಇದೀಗ ಮರುಪ್ರಾರಂಭಿಸು</translation>
<translation id="7180611975245234373">ರೀಫ್ರೆಶ್ ಮಾಡಿ</translation>
<translation id="7182878459783632708">ಯಾವುದೇ ನೀತಿಗಳನ್ನು ಹೊಂದಿಸಿಲ್ಲ</translation>
-<translation id="7186367841673660872">ಈ ಪುಟವನ್ನು<ph name="ORIGINAL_LANGUAGE"/>ನಿಂದ<ph name="LANGUAGE_LANGUAGE"/>ಗೆ ಭಾಷಾಂತರಿಸಲಾಗಿದೆ</translation>
+<translation id="7186367841673660872">ಈ ಪುಟವನ್ನು<ph name="ORIGINAL_LANGUAGE" />ನಿಂದ<ph name="LANGUAGE_LANGUAGE" />ಗೆ ಭಾಷಾಂತರಿಸಲಾಗಿದೆ</translation>
<translation id="719464814642662924">ವೀಸಾ</translation>
-<translation id="7208899522964477531"><ph name="SEARCH_TERMS"/> ಗಾಗಿ <ph name="SITE_NAME"/> ಹುಡುಕಿ</translation>
+<translation id="7208899522964477531"><ph name="SEARCH_TERMS" /> ಗಾಗಿ <ph name="SITE_NAME" /> ಹುಡುಕಿ</translation>
+<translation id="725866823122871198">ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನ ದಿನಾಂಕ ಮತ್ತು ಸಮಯ (<ph name="DATE_AND_TIME" />) ತಪ್ಪಾಗಿರುವುದರಿಂದ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ಗೆ ಖಾಸಗಿ ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ.</translation>
<translation id="7275334191706090484">ನಿರ್ವಹಿಸಿದ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="7298195798382681320">ಶಿಫಾರಸು ಮಾಡಲಾಗಿದೆ</translation>
<translation id="7334320624316649418">&amp;ಮರುಕ್ರಮಗೊಳಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">ಕಡ್ಡಾಯ</translation>
<translation id="7542995811387359312">ಈ ಫಾರ್ಮ್ ಸುರಕ್ಷಿತವಾದ ಸಂಪರ್ಕವನ್ನು ಬಳಸುತ್ತಿಲ್ಲವಾದ ಕಾರಣ ಸ್ವಯಂಚಾಲಿತ ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಭರ್ತಿ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ.</translation>
-<translation id="7568593326407688803">ಈ ಪುಟವು<ph name="ORIGINAL_LANGUAGE"/>ನಲ್ಲಿದೆ ನೀವು ಅದನ್ನು ಭಾಷಾಂತರಿಸಲು ಬಯಸುವಿರಾ?</translation>
+<translation id="7567204685887185387">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವನ್ನು ವಂಚನೆಯಿಂದ ನೀಡಿರಬಹುದು. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
+<translation id="7568593326407688803">ಈ ಪುಟವು<ph name="ORIGINAL_LANGUAGE" />ನಲ್ಲಿದೆ ನೀವು ಅದನ್ನು ಭಾಷಾಂತರಿಸಲು ಬಯಸುವಿರಾ?</translation>
<translation id="7569952961197462199">Chrome ನಿಂದ ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ತೆಗೆದುಹಾಕುವುದೇ?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/> ಅನ್ನು ಎಂದಿಗೂ ಅನುವಾದಿಸಬೇಡ</translation>
-<translation id="7610193165460212391">ಮೌಲ್ಯವು ವ್ಯಾಪ್ತಿಯಿಂದ <ph name="VALUE"/> ಹೊರಗಿದೆ.</translation>
+<translation id="7592362899630581445">ಸರ್ವರ್ ಪ್ರಮಾಣಪತ್ರವು ಹೆಸರಿನ ನಿರ್ಬಂಧನೆಗಳನ್ನು ಉಲ್ಲಂಘಿಸುತ್ತದೆ.</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" /> ಅನ್ನು ಎಂದಿಗೂ ಅನುವಾದಿಸಬೇಡ</translation>
+<translation id="7610193165460212391">ಮೌಲ್ಯವು ವ್ಯಾಪ್ತಿಯಿಂದ <ph name="VALUE" /> ಹೊರಗಿದೆ.</translation>
+<translation id="7674629440242451245">ಉತ್ತಮವಾದ ಹೊಸ Chrome ವೈಶಿಷ್ಟ್ಯಗಳಲ್ಲಿ ಆಸಕ್ತಿ ಇದೆಯೇ? chrome.com/dev ನಲ್ಲಿ ನಮ್ಮ dev ಚಾನಲ್ ಪ್ರಯತ್ನಿಸಿ.</translation>
<translation id="7752995774971033316">ನಿರ್ವಹಣೆಯಲ್ಲಿಲ್ಲ</translation>
+<translation id="7761701407923456692">ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರವು URL ಗೆ ಸರಿ ಹೊಂದುವುದಿಲ್ಲ.</translation>
<translation id="777702478322588152">Prefecture</translation>
<translation id="7791543448312431591">ಸೇರಿಸು</translation>
<translation id="7805768142964895445">ಸ್ಥಿತಿ</translation>
<translation id="7813600968533626083">Chrome ನಿಂದ ಫಾರ್ಮ್ ಸಲಹೆಯನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?</translation>
<translation id="7887683347370398519">ನಿಮ್ಮ CVC ಅನ್ನು ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ</translation>
<translation id="7935318582918952113">DOM ಡಿಸ್ಟಿಲರ್</translation>
+<translation id="7938958445268990899">ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಇನ್ನೂ ಮಾನ್ಯಗೊಳಿಸಿಲ್ಲ.</translation>
<translation id="7956713633345437162">ಮೊಬೈಲ್ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="7961015016161918242">ಎಂದಿಗೂ ಇಲ್ಲ</translation>
<translation id="7977590112176369853">&lt;ಪ್ರಶ್ನೆ ನಮೂದಿಸಿ&gt;</translation>
-<translation id="7983301409776629893">ಯಾವಾಗಲೂ <ph name="ORIGINAL_LANGUAGE"/> ಅನ್ನು <ph name="TARGET_LANGUAGE"/> ಗೆ ಅನುವಾದಿಸಿ</translation>
+<translation id="7983301409776629893">ಯಾವಾಗಲೂ <ph name="ORIGINAL_LANGUAGE" /> ಅನ್ನು <ph name="TARGET_LANGUAGE" /> ಗೆ ಅನುವಾದಿಸಿ</translation>
<translation id="7988324688042446538">ಡೆಸ್ಕ್‌ಟಾಪ್ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="7995512525968007366">ನಿರ್ದಿಷ್ಟಪಡಿಸಲಾಗಿಲ್ಲ</translation>
-<translation id="8034522405403831421">ಈ ಪುಟವು <ph name="SOURCE_LANGUAGE"/> ನಲ್ಲಿ ಇದೆ. ಇದನ್ನು <ph name="TARGET_LANGUAGE"/> ಗೆ ಅನುವಾದಿಸುವುದೇ?</translation>
+<translation id="8003882219468422867">ಎಂಟರ್‌ಪ್ರೈಸ್ ಅತಿಕ್ರಮಣ</translation>
+<translation id="8034522405403831421">ಈ ಪುಟವು <ph name="SOURCE_LANGUAGE" /> ನಲ್ಲಿ ಇದೆ. ಇದನ್ನು <ph name="TARGET_LANGUAGE" /> ಗೆ ಅನುವಾದಿಸುವುದೇ?</translation>
<translation id="8088680233425245692">ಲೇಖನವನ್ನು ವೀಕ್ಷಿಸಲು ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="8091372947890762290">ಸರ್ವರ್‌ನಲ್ಲಿ ಸಕ್ರಿಯತೆ ಬಾಕಿ ಉಳಿದಿದೆ</translation>
<translation id="8194797478851900357">&amp;ಸರಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸು</translation>
-<translation id="8201077131113104583">&quot;<ph name="EXTENSION_ID"/>&quot; ID ಜೊತೆಗಿನ ವಿಸ್ತರಣೆಗೆ ಅಮಾನ್ಯವಾದ ಅಪ್‌ಡೇಟ್‌‌ URL.</translation>
+<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" ID ಜೊತೆಗಿನ ವಿಸ್ತರಣೆಗೆ ಅಮಾನ್ಯವಾದ ಅಪ್‌ಡೇಟ್‌‌ URL.</translation>
<translation id="8208216423136871611">ಉಳಿಸಬೇಡಿ</translation>
<translation id="8218327578424803826">ನಿಯೋಜಿಸಲಾದ ಸ್ಥಳ:</translation>
<translation id="8249320324621329438">ಕಳೆದ ಬಾರಿ ಪಡೆದಿರುವುದು:</translation>
+<translation id="8294431847097064396">ಮೂಲ</translation>
<translation id="8308427013383895095">ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕದಲ್ಲಿನ ಸಮಸ್ಯೆಯಿಂದಾಗಿ ಭಾಷಾಂತರವು ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="8311778656528046050">ಈ ಪುಟವನ್ನು ಮರುಲೋಡ್ ಮಾಡುವುದು ಖಚಿತವೇ?</translation>
<translation id="8349305172487531364">ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳ ಬಾರ್</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">ಇದಕ್ಕೆ ಅನ್ವಯಿಸಲಾಗುತ್ತದೆ</translation>
<translation id="8530504477309582336">ಈ ಪ್ರಕಾರದ ಕಾರ್ಡ್ ಅನ್ನು Google Payments ಬೆಂಬಲಿಸುವುದಿಲ್ಲ. ದಯವಿಟ್ಟು ಬೇರೆ ಕಾರ್ಡ್ ಆಯ್ಕೆಮಾಡಿ.</translation>
<translation id="8553075262323480129">ಪುಟದ ಭಾಷೆಯನ್ನು ಗುರುತಿಸಲು ಅಸಾಧ್ಯವಾದ ಕಾರಣ ಭಾಷಾಂತರವು ವಿಫಲವಾಗಿದೆ.</translation>
-<translation id="8571890674111243710"><ph name="LANGUAGE"/> ಗೆ ಪುಟವನ್ನು ಭಾಷಾಂತರಿಸಲಾಗುತ್ತಿದೆ...</translation>
+<translation id="8559762987265718583"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ಗೆ ಖಾಸಗಿ ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ ಏಕೆಂದರೆ ನಿಮ್ಮ ಸಾಧನದ ದಿನಾಂಕ ಮತ್ತು ಸಮಯ (<ph name="DATE_AND_TIME" />) ತಪ್ಪಾಗಿದೆ.</translation>
+<translation id="8571890674111243710"><ph name="LANGUAGE" /> ಗೆ ಪುಟವನ್ನು ಭಾಷಾಂತರಿಸಲಾಗುತ್ತಿದೆ...</translation>
+<translation id="8647750283161643317">ಎಲ್ಲವನ್ನೂ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರುಹೊಂದಿಸಿ</translation>
<translation id="8713130696108419660">ತಪ್ಪಾದ ಇನಿಷಿಯಲ್ ಸಹಿ</translation>
<translation id="8725066075913043281">ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ</translation>
+<translation id="8738058698779197622">ಸುರಕ್ಷಿತ ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಲು, ನಿಮ್ಮ ಗಡಿಯಾರವನ್ನು ಸರಿಯಾಗಿ ಹೊಂದಿಸುವ ಅಗತ್ಯವಿದೆ. ವೆಬ್‌ಸೈಟ್‌ಗಳು ತಮ್ಮನ್ನು ಗುರುತಿಸಲು ಬಳಸುವ ಪ್ರಮಾಣಪತ್ರಗಳು ಸಮಯದ ನಿರ್ದಿಷ್ಟ ಅವಧಿಗಳಲ್ಲಿ ಮಾತ್ರ ಮಾನ್ಯವಾಗಿರುವ ಕಾರಣ ಹೀಗಾಗುತ್ತದೆ. ನಿಮ್ಮ ಸಾಧನದ ಗಡಿಯಾರವು ತಪ್ಪಾಗಿರುವ ಕಾರಣ, Chromium ಗೆ ಈ ಪ್ರಮಾಣಪತ್ರಗಳನ್ನು ಪರಿಶೀಲಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ.</translation>
<translation id="8790007591277257123">&amp;ಅಳಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="8804164990146287819">ಗೌಪ್ಯತಾ ನೀತಿ</translation>
+<translation id="8820817407110198400">ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="8824019021993735287">ಈ ಸಮಯದಲ್ಲಿ Chrome ಗೆ ನಿಮ್ಮ ಕಾರ್ಡ್ ಅನ್ನು ಪರಿಶೀಲಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ದಯವಿಟ್ಟು ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</translation>
<translation id="8834246243508017242">ಸಂಪರ್ಕಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಸ್ವಯಂತುಂಬುವಿಕೆಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸು…</translation>
<translation id="883848425547221593">ಇತರ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು:</translation>
+<translation id="884923133447025588">ವಿಫಲವಾದ ಕಾರ್ಯತಂತ್ರ ಪತ್ತೆಯಾಗಿಲ್ಲ.</translation>
<translation id="8866481888320382733">ನೀತಿಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಪಾಸ್ ಮಾಡುವಲ್ಲಿ ದೋಷ</translation>
<translation id="8876793034577346603">ಪಾರ್ಸ್ ಮಾಡಬೇಕಾಗಿರುವ ನೆಟ್‌ವರ್ಕ್ ಕಾನ್ಫಿಗರೇಶನ್ ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="8891727572606052622">ಅಮಾನ್ಯವಾದ ಪ್ರಾಕ್ಸಿ ಮೋಡ್.</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/> ಆದೇಶವನ್ನು ಚಾಲನೆಮಾಡಿ: <ph name="SEARCH_TERMS"/> </translation>
+<translation id="889901481107108152">ಕ್ಷಮಿಸಿ, ಈ ಪ್ರಯೋಗವು ನಿಮ್ಮ ಪ್ಲ್ಯಾಟ್‌ಫಾರ್ಮ್‌ನಲ್ಲಿ ಲಭ್ಯವಿಲ್ಲ.</translation>
+<translation id="8903921497873541725">ಜೂಮ್ ಇನ್</translation>
+<translation id="8932102934695377596">ನಿಮ್ಮ ಗಡಿಯಾರ ಹಿಂದೆ ಇದೆ</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" /> ಆದೇಶವನ್ನು ಚಾಲನೆಮಾಡಿ: <ph name="SEARCH_TERMS" /> </translation>
+<translation id="8971063699422889582">ಸರ್ವರ್‌ನ ಪ್ರಕಮಾಣಪತ್ರದ ಅವಧಿ ಮುಕ್ತಾಯಗೊಂಡಿದೆ.</translation>
<translation id="8988760548304185580">ನಿಮ್ಮ ಕಾರ್ಡ್‌ನ ಹಿಂದಿರುವ ಮುಕ್ತಾಯದ ದಿನಾಂಕ ಮತ್ತು 3-ಅಂಕಿಗಳ CVC ಅನ್ನು ನಮೂದಿಸಿ</translation>
-<translation id="9020542370529661692">ಈ ಪುಟವನ್ನು <ph name="TARGET_LANGUAGE"/> ಗೆ ಅನುವಾದಿಸಲಾಗಿದೆ</translation>
+<translation id="901974403500617787">ಸಿಸ್ಟಂನಾದ್ಯಂತ ಅನ್ವಯವಾಗುವ ಫ್ಲ್ಯಾಗ್‌ಗಳನ್ನು ಮಾಲೀಕರಿಂದ ಮಾತ್ರ ಹೊಂದಿಸಲು ಸಾಧ್ಯ: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">ಈ ಪುಟವನ್ನು <ph name="TARGET_LANGUAGE" /> ಗೆ ಅನುವಾದಿಸಲಾಗಿದೆ</translation>
+<translation id="9049981332609050619">ನೀವು <ph name="DOMAIN" /> ಅನ್ನು ತಲುಪಲು ಪ್ರಯತ್ನಿಸಿರುವಿರಿ, ಆದರೆ ಸರ್ವರ್ ಅಮಾನ್ಯ ಪ್ರಮಾಣಪತ್ರವನ್ನು ನೀಡಿದೆ.</translation>
<translation id="9125941078353557812">ನಿಮ್ಮ ಕಾರ್ಡ್ ಹಿಂಭಾಗದಲ್ಲಿರುವ 3-ಅಂಕಿಗಳ CVC ಅನ್ನು ನಮೂದಿಸಿ</translation>
<translation id="9137013805542155359">ಮೂಲವನ್ನು ತೋರಿಸಿ</translation>
<translation id="9148507642005240123">&amp;ಸಂಪಾದಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
<translation id="9154176715500758432">ಈ ಪುಟದಲ್ಲಿ ನಿಲ್ಲಿ</translation>
<translation id="9170848237812810038">&amp;ರದ್ದುಮಾಡು</translation>
+<translation id="917450738466192189">ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರವು ಅಮಾನ್ಯವಾಗಿದೆ.</translation>
+<translation id="9187827965378254003">ಓಹೋ, ಪ್ರಸ್ತುತ ಯಾವುದೇ ಪ್ರಯೋಗಗಳು ಲಭ್ಯವಿಲ್ಲ ಎಂದು ತೋರುತ್ತಿದೆ.</translation>
<translation id="9207861905230894330">ಲೇಖನವನ್ನು ಸೇರಿಸಲು ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ಫಾರ್ಮ್ ತೆರವುಗೊಳಿಸಿ</translation>
+<translation id="988159990683914416">ಡೆವಲಪರ್ ಬಿಲ್ಡ್</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ko.xtb b/chromium/components/strings/components_strings_ko.xtb
index 2c01e073b25..8c8909447cd 100644
--- a/chromium/components/strings/components_strings_ko.xtb
+++ b/chromium/components/strings/components_strings_ko.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ko">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ko">
+<translation id="1032854598605920125">시계 방향으로 회전</translation>
<translation id="1055184225775184556">추가 실행 취소(&amp;U)</translation>
<translation id="106701514854093668">데스크톱 북마크</translation>
-<translation id="1103523840287552314"><ph name="LANGUAGE"/> 항상 번역</translation>
+<translation id="1080116354587839789">너비에 맞춤</translation>
+<translation id="1103523840287552314"><ph name="LANGUAGE" /> 항상 번역</translation>
<translation id="1113869188872983271">재정렬 실행 취소(&amp;U)</translation>
<translation id="111844081046043029">이 페이지에서 벗어나시겠습니까?</translation>
<translation id="112840717907525620">정책 캐시 확인</translation>
<translation id="1132774398110320017">Chrome 자동완성 설정...</translation>
-<translation id="1152921474424827756"><ph name="URL"/>의 <ph name="BEGIN_LINK"/>캐시된 사본<ph name="END_LINK"/>에 액세스</translation>
+<translation id="1150979032973867961">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 컴퓨터의 운영체제에서 신뢰하는 보안 인증서가 아닙니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
+<translation id="1152921474424827756"><ph name="URL" />의 <ph name="BEGIN_LINK" />캐시된 사본<ph name="END_LINK" />에 액세스</translation>
+<translation id="121201262018556460"><ph name="DOMAIN" />에 접속하려 했으나 서버가 안전성이 낮은 키가 포함된 인증서를 전달했습니다. 공격자가 비공개 키를 손상시켰을 수 있으며 서버를 가장한 공격자와 통신 중일 수 있습니다.</translation>
<translation id="1227224963052638717">알 수 없는 정책입니다.</translation>
<translation id="1227633850867390598">값 숨기기</translation>
<translation id="1228893227497259893">잘못된 개체 식별자</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">등록 도메인:</translation>
<translation id="1344588688991793829">Chromium 자동완성 설정...</translation>
<translation id="1426410128494586442">예</translation>
+<translation id="1430915738399379752">인쇄</translation>
<translation id="1455235771979731432">카드를 인증하는 중에 문제가 발생했습니다. 인터넷 연결을 확인하고 다시 시도하세요.</translation>
<translation id="1491151370853475546">페이지 새로고침</translation>
<translation id="1549470594296187301">이 기능을 이용하려면 자바스크립트를 사용하도록 설정해야 합니다.</translation>
-<translation id="1639239467298939599">로드 중</translation>
<translation id="1640180200866533862">사용자 정책</translation>
<translation id="1644184664548287040">네트워크 구성이 잘못되어 가져올 수 없습니다.</translation>
-<translation id="1693754753824026215"><ph name="SITE"/>의 페이지 내용:</translation>
+<translation id="1655462015569774233">{1,plural, =1{서버의 보안 인증서가 어제 만료되어 <ph name="DOMAIN" />임을 입증할 수 없습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다. 현재 컴퓨터의 시계가 <ph name="CURRENT_DATE" />로 설정되어 있습니다. 시간이 정확하지 않으면 시스템 시계를 수정한 뒤 이 페이지를 새로고침하세요.}other{서버의 보안 인증서가 #일 전에 만료되어 <ph name="DOMAIN" />임을 입증할 수 없습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다. 현재 컴퓨터의 시계가 <ph name="CURRENT_DATE" />로 설정되어 있습니다. 시간이 정확하지 않으면 시스템 시계를 수정한 뒤 이 페이지를 새로고침하세요.}}</translation>
+<translation id="168841957122794586">서버 인증서에 안전성이 낮은 암호화 키가 포함되어 있습니다.</translation>
+<translation id="1693754753824026215"><ph name="SITE" />의 페이지 내용:</translation>
+<translation id="1706954506755087368">{1,plural, =1{서버의 보안 인증서가 내일 발효될 예정이며 이에 따라 <ph name="DOMAIN" />임을 입증할 수 없습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.}other{서버의 보안 인증서가 #일 후 발효될 예정이며 이에 따라 <ph name="DOMAIN" />임을 입증할 수 없습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 기기의 운영체제에서 신뢰하는 보안 인증서가 아닙니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
<translation id="1821930232296380041">잘못된 요청 또는 요청 매개변수</translation>
-<translation id="1853748787962613237">글을 표시하지 못했습니다.</translation>
<translation id="1871208020102129563">프록시가 .pac 스크립트 URL이 아닌 고정 프록시 서버를 사용하도록 설정됩니다.</translation>
-<translation id="1875753206475436906">휴리스틱 유형: <ph name="HEURISTIC_TYPE"/>
- 서버 유형: <ph name="SERVER_TYPE"/>
- 필드 서명: <ph name="FIELD_SIGNATURE"/>
- 양식 서명: <ph name="FORM_SIGNATURE"/>
- 실험 ID: '<ph name="EXPERIMENT_ID"/>'</translation>
-<translation id="194030505837763158"><ph name="LINK"/>(으)로 이동</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> 북마크</translation>
+<translation id="194030505837763158"><ph name="LINK" />(으)로 이동</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> 북마크</translation>
<translation id="1973335181906896915">일련화 오류</translation>
+<translation id="1974060860693918893">고급</translation>
<translation id="2025186561304664664">프록시가 자동 설정되도록 지정됩니다.</translation>
<translation id="2025623846716345241">새로고침 확인</translation>
-<translation id="2030481566774242610"><ph name="LINK"/>을(를) 찾으셨나요?</translation>
+<translation id="2030481566774242610"><ph name="LINK" />을(를) 찾으셨나요?</translation>
<translation id="2053553514270667976">우편번호</translation>
<translation id="20817612488360358">시스템 프록시 설정이 사용하도록 설정되었지만 명시적 프록시 설정도 지정되어 있습니다.</translation>
<translation id="2094505752054353250">도메인이 일치하지 않음</translation>
<translation id="2096368010154057602">자치구</translation>
<translation id="2113977810652731515">카드</translation>
-<translation id="2114841414352855701"><ph name="POLICY_NAME"/>이(가) 우선 적용되었기 때문에 무시됩니다.</translation>
+<translation id="2114841414352855701"><ph name="POLICY_NAME" />이(가) 우선 적용되었기 때문에 무시됩니다.</translation>
+<translation id="2128531968068887769">네이티브 클라이언트</translation>
<translation id="213826338245044447">모바일 북마크</translation>
+<translation id="2171101176734966184"><ph name="DOMAIN" />에 접속하려 했으나 서버에서 안전성이 낮은 서명 알고리즘을 사용하여 서명된 인증서를 전달했습니다. 이는 서버에서 전달한 보안 자격증명 정보가 위조되었을 수 있으며 서버를 가장한 공격자와 통신 중일 수 있음을 의미합니다.</translation>
<translation id="2181821976797666341">정책</translation>
<translation id="2212735316055980242">정책을 찾을 수 없음</translation>
<translation id="2213606439339815911">항목을 가져오는 중...</translation>
<translation id="225207911366869382">이 값은 이 정책에 사용되지 않습니다.</translation>
<translation id="2262243747453050782">HTTP 오류</translation>
-<translation id="2270192940992995399">글을 찾지 못했습니다.</translation>
-<translation id="2328300916057834155"><ph name="ENTRY_INDEX"/> 색인의 잘못된 북마크 무시됨</translation>
+<translation id="2282872951544483773">사용할 수 없는 실험</translation>
+<translation id="229702904922032456">루트 또는 중개 인증서가 만료되었습니다.</translation>
+<translation id="2328300916057834155"><ph name="ENTRY_INDEX" /> 색인의 잘못된 북마크 무시됨</translation>
<translation id="2354001756790975382">기타 북마크</translation>
<translation id="2359808026110333948">계속</translation>
<translation id="2367567093518048410">수준</translation>
+<translation id="2384307209577226199">엔터프라이즈 기본값</translation>
+<translation id="2386255080630008482">서버 인증서가 폐기되었습니다.</translation>
<translation id="2392959068659972793">값이 설정되지 않은 정책 표시</translation>
<translation id="2396249848217231973">삭제 실행 취소(&amp;U)</translation>
+<translation id="2413528052993050574">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 서버의 보안 인증서가 취소될 수 있습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
<translation id="2455981314101692989">이 웹페이지에서는 이 양식에 대한 자동완성 기능을 사용할 수 없습니다.</translation>
<translation id="2479410451996844060">검색 URL이 잘못됨</translation>
+<translation id="2491120439723279231">서버 인증서에 오류가 있습니다.</translation>
<translation id="2495083838625180221">JSON 파서</translation>
<translation id="2498091847651709837">새 카드 스캔</translation>
<translation id="2556876185419854533">수정 실행 취소(&amp;U)</translation>
-<translation id="2581221116934462656">다음에 <ph name="PRODUCT_NAME"/>에서 이 사이트의 <ph name="LANGUAGE_NAME"/> 페이지를 번역하시겠습니까?</translation>
+<translation id="2581221116934462656">다음에 <ph name="PRODUCT_NAME" />에서 이 사이트의 <ph name="LANGUAGE_NAME" /> 페이지를 번역하시겠습니까?</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">문서가 비밀번호로 보호되고 있습니다. 비밀번호를 입력하세요.</translation>
+<translation id="2625385379895617796">시간이 너무 먼 미래로 설정되어 있습니다.</translation>
<translation id="2639739919103226564">상태:</translation>
+<translation id="2653659639078652383">제출</translation>
<translation id="2704283930420550640">값이 형식과 일치하지 않습니다.</translation>
<translation id="2721148159707890343">요청 성공</translation>
+<translation id="2728127805433021124">서버의 인증서가 안전성이 낮은 서명 알고리즘을 사용하여 서명되어 있습니다.</translation>
<translation id="2774256287122201187">계속 사용할 수 있습니다. 이 페이지를 계속 이용하는 경우 5분 동안 이 경고가 다시 표시되지 않습니다.</translation>
<translation id="277499241957683684">기기 기록 없음</translation>
<translation id="2835170189407361413">서식 지우기</translation>
-<translation id="2855922900409897335"><ph name="CREDIT_CARD"/> 인증</translation>
+<translation id="2855922900409897335"><ph name="CREDIT_CARD" /> 인증</translation>
+<translation id="2915500479781995473">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 서버의 보안 인증서가 만료되었습니다. 서버를 잘못 설정했거나 해커가 연결을 가로채고 있기 때문일 수 있습니다. 컴퓨터의 시계가 현재 <ph name="CURRENT_TIME" />(으)로 설정되어 있습니다. 시간이 정확하지 않으면 시스템 시계를 수정한 다음 이 페이지를 새로고침하세요.</translation>
+<translation id="2922350208395188000">서버 인증서를 확인할 수 없습니다.</translation>
+<translation id="2941952326391522266">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 서버의 보안 인증서가 <ph name="DOMAIN2" />에서 제공한 것입니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
<translation id="2958431318199492670">네트워크 설정이 ONC 표준을 준수하지 않습니다. 일부 설정을 가져올 수 없습니다.</translation>
<translation id="2972581237482394796">다시 실행(&amp;R)</translation>
-<translation id="3010559122411665027">목록 항목 '<ph name="ENTRY_INDEX"/>': <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">목록 항목 '<ph name="ENTRY_INDEX" />': <ph name="ERROR" /></translation>
<translation id="3024663005179499861">잘못된 정책 유형</translation>
<translation id="3105172416063519923">애셋 ID:</translation>
<translation id="3145945101586104090">응답 디코딩 실패</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">섬</translation>
<translation id="3219579145727097045">신용카드의 유효기간과 카드 앞면의 4자리 CVC를 입력하세요.</translation>
-<translation id="3228969707346345236">페이지가 <ph name="LANGUAGE"/>(으)로 되어 있으므로 번역하지 못했습니다.</translation>
+<translation id="3225919329040284222">서버가 내장된 기대치와 일치하지 않는 인증서를 전달했습니다. 이러한 기대치는 사용자를 보호하기 위해 보안이 엄격한 특정 웹사이트에 포함됩니다.</translation>
+<translation id="3228969707346345236">페이지가 <ph name="LANGUAGE" />(으)로 되어 있으므로 번역하지 못했습니다.</translation>
<translation id="3270847123878663523">재정렬 실행 취소(&amp;U)</translation>
+<translation id="3286538390144397061">지금 다시 시작</translation>
<translation id="333371639341676808">이 페이지가 추가적인 대화를 생성하지 않도록 차단합니다.</translation>
-<translation id="3369366829301677151"><ph name="CREDIT_CARD"/> 업데이트 및 확인</translation>
+<translation id="3340978935015468852">설정</translation>
+<translation id="3369192424181595722">시계 오류</translation>
+<translation id="3369366829301677151"><ph name="CREDIT_CARD" /> 업데이트 및 확인</translation>
<translation id="337363190475750230">사용 중단됨</translation>
<translation id="3377188786107721145">정책 파싱 오류</translation>
<translation id="3380365263193509176">알 수 없는 오류가 발생했습니다.</translation>
<translation id="3380864720620200369">클라이언트 ID:</translation>
<translation id="3427342743765426898">수정 다시 실행(&amp;R)</translation>
+<translation id="3435896845095436175">사용</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">가져오기 간격:</translation>
+<translation id="3462200631372590220">세부정보 숨기기</translation>
+<translation id="3528171143076753409">서버의 인증서를 신뢰할 수 없습니다.</translation>
<translation id="3542684924769048008">비밀번호 사용 항목:</translation>
<translation id="3583757800736429874">이동 다시 실행(&amp;R)</translation>
<translation id="3623476034248543066">값 표시</translation>
+<translation id="3648607100222897006">해당 실험용 기능은 언제든지 변경, 중지 및 취소될 수 있습니다. 해당 실험용 기능을 사용할 때 발생하는 일에 대해 Google은 보장하지 않습니다. 데이터가 삭제되거나 개인 정보가 예기치 않은 방법으로 유출될 수 있습니다. 본인이 사용 설정한 모든 실험 기능은 해당 브라우저의 다른 사용자도 사용하게 됩니다. 주의해서 진행하시기 바랍니다.</translation>
<translation id="3650584904733503804">유효성 검사 성공</translation>
<translation id="370665806235115550">로드 중...</translation>
<translation id="3712624925041724820">라이선스 만료됨</translation>
<translation id="3739623965217189342">복사한 링크</translation>
<translation id="375403751935624634">서버 오류가 발생하여 번역하지 못했습니다.</translation>
<translation id="385051799172605136">뒤로</translation>
+<translation id="3858027520442213535">시간과 날짜 업데이트</translation>
<translation id="3884278016824448484">기기 식별자 충돌</translation>
<translation id="3885155851504623709">교구</translation>
<translation id="3934680773876859118">PDF 문서를 로드하지 못했습니다.</translation>
<translation id="3963721102035795474">리더 모드</translation>
<translation id="4030383055268325496">추가 실행 취소(&amp;U)</translation>
-<translation id="4058922952496707368">'<ph name="SUBKEY"/>' 키: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">경고</translation>
+<translation id="4058922952496707368">'<ph name="SUBKEY" />' 키: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">프록시 설정이 고정 프록시 서버가 아닌 .pac 스크립트 URL을 사용하도록 설정됩니다.</translation>
<translation id="409504436206021213">새로고침 안 함</translation>
<translation id="4103249731201008433">기기 일련번호가 잘못됨</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">잘못된 서명</translation>
<translation id="4269787794583293679">(사용자 이름 없음)</translation>
<translation id="4300246636397505754">상위 추천</translation>
-<translation id="4372948949327679948">예상 <ph name="VALUE_TYPE"/> 값입니다.</translation>
+<translation id="4325863107915753736">도움말을 찾지 못했습니다.</translation>
+<translation id="4372948949327679948">예상 <ph name="VALUE_TYPE" /> 값입니다.</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" />에 접속하려 했으나 발행기관에서 서버가 전달한 인증서를 폐기했습니다. 이는 서버가 제시한 보안 자격증명 정보를 신뢰할 수 없음을 의미합니다. 사용자는 현재 공격자와 통신 중일 수도 있습니다.</translation>
+<translation id="4394049700291259645">사용 중지</translation>
+<translation id="4424024547088906515">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 Chrome에서 신뢰하는 보안 인증서가 아닙니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
<translation id="443673843213245140">프록시 사용은 중지되었지만 명시적 프록시 설정이 지정되어 있습니다.</translation>
-<translation id="4506176782989081258">유효성 검사 오류 <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">유효성 검사 오류 <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chrome에서 주소를 삭제하시겠습니까?</translation>
<translation id="4594403342090139922">삭제 실행 취소(&amp;U)</translation>
<translation id="4607653538520819196">이 페이지는 데이터 세이버에 의해 프록시될 수 없습니다.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 서버의 보안 인증서에 오류가 있습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
<translation id="4726672564094551039">정책 새로고침</translation>
+<translation id="4728558894243024398">플랫폼</translation>
+<translation id="4771973620359291008">알 수 없는 오류가 발생했습니다.</translation>
<translation id="4800132727771399293">유효기간과 CVC를 확인한 후 다시 시도해 주세요.</translation>
<translation id="4813512666221746211">네트워크 오류</translation>
+<translation id="4816492930507672669">페이지 맞춤</translation>
<translation id="4850886885716139402">보기</translation>
-<translation id="4923417429809017348">페이지가 알 수 없는 언어에서 <ph name="LANGUAGE_LANGUAGE"/>(으)로 번역되었습니다.</translation>
+<translation id="4923417429809017348">페이지가 알 수 없는 언어에서 <ph name="LANGUAGE_LANGUAGE" />(으)로 번역되었습니다.</translation>
<translation id="4926049483395192435">지정해야 합니다.</translation>
<translation id="4968547170521245791">프록시할 수 없음</translation>
-<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE"/>에서 <ph name="TARGET_LANGUAGE"/>로 번역하시겠습니까?</translation>
+<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE" />에서 <ph name="TARGET_LANGUAGE" />로 번역하시겠습니까?</translation>
<translation id="5019198164206649151">보조 기억 장치 상태가 잘못됨</translation>
<translation id="5031870354684148875">Google 번역 정보</translation>
+<translation id="5045550434625856497">비밀번호가 잘못되었습니다.</translation>
+<translation id="5087286274860437796">서버의 인증서가 현재 유효하지 않습니다.</translation>
<translation id="5089810972385038852">주</translation>
+<translation id="5094747076828555589">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 Chromium에서 신뢰하는 보안 인증서가 아닙니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
<translation id="5095208057601539847">주/도</translation>
<translation id="5145883236150621069">정책 응답에 오류 코드가 포함되어 있음</translation>
<translation id="5172758083709347301">컴퓨터</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/>가 아닙니까? 오류 신고</translation>
+<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" />가 아닙니까? 오류 신고</translation>
<translation id="5190835502935405962">북마크바</translation>
+<translation id="5199729219167945352">실험실 기능</translation>
+<translation id="5251803541071282808">클라우드</translation>
<translation id="5295309862264981122">탐색 확인</translation>
<translation id="5299298092464848405">정책을 파싱하는 중 오류 발생</translation>
+<translation id="5316812925700871227">반시계 방향으로 회전</translation>
<translation id="5317780077021120954">저장</translation>
<translation id="536296301121032821">정책 설정 저장 실패</translation>
-<translation id="5439770059721715174">'<ph name="ERROR_PATH"/>'에서 스키마 유효성 검사 오류: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없습니다. 서버의 보안 인증서가 현재 유효하지 않습니다. 서버를 잘못 설정했거나 해커가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
+<translation id="5439770059721715174">'<ph name="ERROR_PATH" />'에서 스키마 유효성 검사 오류: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">잘못된 정책 타임스탬프</translation>
<translation id="5470861586879999274">수정 다시 실행(&amp;R)</translation>
<translation id="5509780412636533143">관리 북마크</translation>
<translation id="5523118979700054094">정책 이름</translation>
<translation id="552553974213252141">텍스트가 올바로 추출되었습니까?</translation>
<translation id="5540224163453853">요청한 글을 찾지 못했습니다.</translation>
+<translation id="5556459405103347317">새로고침</translation>
<translation id="5565735124758917034">활성</translation>
<translation id="560412284261940334">관리가 지원되지 않음</translation>
<translation id="5629630648637658800">정책 설정 로드 실패</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">현재 사용자</translation>
<translation id="5813119285467412249">추가 다시 실행(&amp;R)</translation>
<translation id="5872918882028971132">상위 추천</translation>
-<translation id="587701087903783706">모바일 친화적 보기 닫기</translation>
<translation id="59107663811261420">이 판매자의 Google Payments에서 지원하지 않는 카드 유형입니다. 다른 카드를 선택해 주세요.</translation>
+<translation id="5975083100439434680">축소</translation>
<translation id="5989320800837274978">고정 프록시 서버와 .pac 스크립트 URL이 모두 지정되지 않았습니다.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">닫기</translation>
+<translation id="6060685159320643512">이러한 실험실 기능은 문제를 일으킬 수 있습니다.</translation>
+<translation id="6151417162996330722">서버 인증서의 유효 기간이 너무 깁니다.</translation>
<translation id="6154808779448689242">반환된 정책 토큰이 현재 토큰과 일치하지 않음</translation>
<translation id="6165508094623778733">자세히 알아보기</translation>
<translation id="6259156558325130047">재정렬 다시 실행(&amp;R)</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> 북마크</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> 북마크</translation>
<translation id="6282194474023008486">우편번호</translation>
<translation id="6337534724793800597">이름별로 정책 필터링</translation>
+<translation id="6387478394221739770">Chrome의 멋진 새 기능에 관심이 있으십니까? chrome.com/beta 페이지에서 베타 채널을 방문해 보세요.</translation>
+<translation id="6426993025560594914">사용자 플랫폼에서 모든 실험 기능을 사용할 수 있습니다.</translation>
<translation id="6445051938772793705">국가</translation>
<translation id="6458467102616083041">정책에 의해 기본 검색의 사용이 중지되었기 때문에 무시됨</translation>
<translation id="647261751007945333">기기 정책</translation>
<translation id="6512448926095770873">이 페이지 나오기</translation>
<translation id="6529602333819889595">삭제 다시 실행(&amp;R)</translation>
<translation id="6550675742724504774">옵션</translation>
-<translation id="6597614308054261376"><ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>에 접속을 시도하고 있습니다. 이 페이지는 현재 데이터 세이버에 의해 프록시될 수 없습니다.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> 검색</translation>
+<translation id="6597614308054261376"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />에 접속을 시도하고 있습니다. 이 페이지는 현재 데이터 세이버에 의해 프록시될 수 없습니다.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> 검색</translation>
<translation id="6644283850729428850">이 정책은 사용되지 않습니다.</translation>
<translation id="6646897916597483132">카드 앞면의 4자리 CVC를 입력하세요.</translation>
+<translation id="674375294223700098">알 수 없는 서버 인증서 오류입니다.</translation>
<translation id="6753269504797312559">정책 값</translation>
<translation id="6831043979455480757">번역</translation>
<translation id="6839929833149231406">지역</translation>
<translation id="6874604403660855544">추가 다시 실행(&amp;R)</translation>
<translation id="6891596781022320156">정책 수준이 지원되지 않습니다.</translation>
<translation id="6915804003454593391">사용자:</translation>
+<translation id="6957887021205513506">서버의 인증서가 위조된 것 같습니다.</translation>
<translation id="6965382102122355670">확인</translation>
<translation id="6965978654500191972">기기</translation>
<translation id="6970216967273061347">구</translation>
<translation id="6973656660372572881">고정 프록시 서버와 .pac 스크립트 URL이 모두 지정되어 있습니다.</translation>
<translation id="6980028882292583085">자바스크립트 알림</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250"><ph name="DOMAIN" />에 접속하려고 했지만 서버가 제시한 인증서의 유효 기간이 너무 길어서 신뢰할 수 없습니다.</translation>
<translation id="7087282848513945231">카운티</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/>로 번역하지 못했습니다.</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" />로 번역하지 못했습니다.</translation>
<translation id="7139724024395191329">에미리트</translation>
+<translation id="7179921470347911571">지금 다시 시작</translation>
<translation id="7180611975245234373">새로고침</translation>
<translation id="7182878459783632708">설정된 정책 없음</translation>
-<translation id="7186367841673660872">이 페이지는<ph name="ORIGINAL_LANGUAGE"/>에서<ph name="LANGUAGE_LANGUAGE"/>로 번역되었습니다.</translation>
+<translation id="7186367841673660872">이 페이지는<ph name="ORIGINAL_LANGUAGE" />에서<ph name="LANGUAGE_LANGUAGE" />로 번역되었습니다.</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531"><ph name="SITE_NAME"/>에서 <ph name="SEARCH_TERMS"/> 검색</translation>
+<translation id="7208899522964477531"><ph name="SITE_NAME" />에서 <ph name="SEARCH_TERMS" /> 검색</translation>
+<translation id="725866823122871198">컴퓨터의 날짜와 시간(<ph name="DATE_AND_TIME" />)이 잘못되어 <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />에 대한 비공개 연결을 설정할 수 없습니다.</translation>
<translation id="7275334191706090484">관리 북마크</translation>
<translation id="7298195798382681320">권장</translation>
<translation id="7334320624316649418">재정렬 다시 실행(&amp;R)</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">자바스크립트</translation>
<translation id="7537536606612762813">필수</translation>
<translation id="7542995811387359312">양식에 보안 연결이 사용되지 않아 신용카드 자동 채우기가 사용 중지되었습니다.</translation>
-<translation id="7568593326407688803">이 페이지는<ph name="ORIGINAL_LANGUAGE"/>로 되어 있습니다. 번역하시겠습니까?</translation>
+<translation id="7567204685887185387">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 서버의 보안 인증서가 부정한 방식으로 발행되었을 수 있습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
+<translation id="7568593326407688803">이 페이지는<ph name="ORIGINAL_LANGUAGE" />로 되어 있습니다. 번역하시겠습니까?</translation>
<translation id="7569952961197462199">Chrome에서 신용카드를 삭제하시겠습니까?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/> 번역 안함</translation>
-<translation id="7610193165460212391">값(<ph name="VALUE"/>)이 범위를 벗어났습니다.</translation>
+<translation id="7592362899630581445">서버의 인증서가 이름 제약 조건을 위반합니다.</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" /> 번역 안함</translation>
+<translation id="7610193165460212391">값(<ph name="VALUE" />)이 범위를 벗어났습니다.</translation>
+<translation id="7674629440242451245">Chrome의 멋진 새 기능에 관심이 있으십니까? chrome.com/dev 페이지에서 개발자 채널에 방문해 보세요.</translation>
<translation id="7752995774971033316">관리되지 않음</translation>
+<translation id="7761701407923456692">서버의 인증서가 URL과 일치하지 않습니다.</translation>
<translation id="777702478322588152">도</translation>
<translation id="7791543448312431591">추가</translation>
<translation id="7805768142964895445">상태</translation>
<translation id="7813600968533626083">Chrome에서 추천검색어를 삭제하시겠습니까?</translation>
<translation id="7887683347370398519">CVC를 확인한 후 다시 시도하세요.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">서버 인증서가 유효하지 않습니다.</translation>
<translation id="7956713633345437162">모바일 북마크</translation>
<translation id="7961015016161918242">완료되지 않음</translation>
<translation id="7977590112176369853">&lt;검색어 입력&gt;</translation>
-<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE"/>를 항상 <ph name="TARGET_LANGUAGE"/>로 번역</translation>
+<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE" />를 항상 <ph name="TARGET_LANGUAGE" />로 번역</translation>
<translation id="7988324688042446538">데스크톱 북마크</translation>
<translation id="7995512525968007366">지정되지 않음</translation>
-<translation id="8034522405403831421">이 페이지는 <ph name="SOURCE_LANGUAGE"/>로 되어 있습니다. <ph name="TARGET_LANGUAGE"/>로 번역하시겠습니까?</translation>
+<translation id="8003882219468422867">엔터프라이즈 재정의</translation>
+<translation id="8034522405403831421">이 페이지는 <ph name="SOURCE_LANGUAGE" />로 되어 있습니다. <ph name="TARGET_LANGUAGE" />로 번역하시겠습니까?</translation>
<translation id="8088680233425245692">글을 조회하지 못했습니다.</translation>
<translation id="8091372947890762290">활성화 요청이 서버에서 대기 중</translation>
<translation id="8194797478851900357">이동 실행 취소(&amp;U)</translation>
-<translation id="8201077131113104583">ID가 '<ph name="EXTENSION_ID"/>'인 확장 프로그램에 대한 잘못된 업데이트 URL</translation>
+<translation id="8201077131113104583">ID가 '<ph name="EXTENSION_ID" />'인 확장 프로그램에 대한 잘못된 업데이트 URL</translation>
<translation id="8208216423136871611">저장하지 않음</translation>
<translation id="8218327578424803826">지정된 위치:</translation>
<translation id="8249320324621329438">마지막으로 가져온 시간:</translation>
+<translation id="8294431847097064396">출처</translation>
<translation id="8308427013383895095">네트워크 연결 문제로 인해 번역에 실패했습니다.</translation>
<translation id="8311778656528046050">이 페이지를 새로고침 하시겠습니까?</translation>
<translation id="8349305172487531364">북마크바</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">적용 대상</translation>
<translation id="8530504477309582336">Google Payments에서 지원하지 않는 카드 유형입니다. 다른 카드를 선택해 주세요.</translation>
<translation id="8553075262323480129">페이지의 언어를 결정할 수 없으므로 번역하지 못했습니다.</translation>
-<translation id="8571890674111243710">페이지를 <ph name="LANGUAGE"/>(으)로 번역 중...</translation>
+<translation id="8559762987265718583">기기의 날짜와 시간(<ph name="DATE_AND_TIME" />)이 잘못되어 <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />에 대한 비공개 연결을 설정할 수 없습니다.</translation>
+<translation id="8571890674111243710">페이지를 <ph name="LANGUAGE" />(으)로 번역 중...</translation>
+<translation id="8647750283161643317">기본값으로 재설정</translation>
<translation id="8713130696108419660">잘못된 초기 서명</translation>
<translation id="8725066075913043281">다시 시도하세요</translation>
+<translation id="8738058698779197622">보안 연결을 설정하려면 시계가 올바로 설정되어 있어야 합니다. 웹사이트가 자신을 식별하는 데 사용하는 인증서가 특정 기간에만 유효하기 때문입니다. 기기의 시계가 잘못 설정되어 Chromium에서 이 인증서를 확인할 수 없습니다.</translation>
<translation id="8790007591277257123">삭제 다시 실행(&amp;R)</translation>
<translation id="8804164990146287819">개인정보취급방침</translation>
+<translation id="8820817407110198400">북마크</translation>
<translation id="8824019021993735287">현재 Chrome에서 카드를 확인할 수 없습니다. 나중에 다시 시도해 주세요.</translation>
<translation id="8834246243508017242">주소록을 사용해 자동완성 기능 사용 설정…</translation>
<translation id="883848425547221593">기타 북마크</translation>
+<translation id="884923133447025588">폐기 매커니즘을 찾을 수 없습니다.</translation>
<translation id="8866481888320382733">정책 설정을 파싱하는 중 오류 발생</translation>
<translation id="8876793034577346603">네트워크 설정을 파싱하지 못했습니다.</translation>
<translation id="8891727572606052622">프록시 모드가 잘못되었습니다.</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/> 명령어 실행: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">죄송합니다. 현재 플랫폼에서 사용할 수 없는 실험실 기능입니다.</translation>
+<translation id="8903921497873541725">확대</translation>
+<translation id="8932102934695377596">시간이 너무 먼 과거로 설정되어 있습니다.</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" /> 명령어 실행: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">서버 인증서가 만료되었습니다.</translation>
<translation id="8988760548304185580">신용카드의 유효기간과 카드 뒷면의 3자리 CVC를 입력하세요.</translation>
-<translation id="9020542370529661692">이 페이지는 <ph name="TARGET_LANGUAGE"/>로 번역되었습니다.</translation>
+<translation id="901974403500617787">시스템 전체에 적용되는 플래그는 소유자(<ph name="OWNER_EMAIL" />)만 설정할 수 있습니다.</translation>
+<translation id="9020542370529661692">이 페이지는 <ph name="TARGET_LANGUAGE" />로 번역되었습니다.</translation>
+<translation id="9049981332609050619"><ph name="DOMAIN" />에 접속하려 했지만 서버가 잘못된 인증서를 전달했습니다.</translation>
<translation id="9125941078353557812">카드 뒷면의 3자리 CVC를 입력하세요.</translation>
<translation id="9137013805542155359">원본 보기</translation>
<translation id="9148507642005240123">수정 실행 취소(&amp;U)</translation>
<translation id="9154176715500758432">이 페이지에 머무르기</translation>
<translation id="9170848237812810038">실행 취소(&amp;U)</translation>
+<translation id="917450738466192189">서버의 인증서가 유효하지 않습니다.</translation>
+<translation id="9187827965378254003">현재 사용 가능한 실험실 기능이 없습니다.</translation>
<translation id="9207861905230894330">글을 추가하지 못했습니다.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">양식 지우기</translation>
+<translation id="988159990683914416">개발자 빌드</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_lt.xtb b/chromium/components/strings/components_strings_lt.xtb
index a402a6ca8a1..f29a8caaba9 100644
--- a/chromium/components/strings/components_strings_lt.xtb
+++ b/chromium/components/strings/components_strings_lt.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="lt">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="lt">
+<translation id="1032854598605920125">Pasukti pagal laikrodžio rodyklę</translation>
<translation id="1055184225775184556">&amp;Anuliuoti pridėjimą</translation>
<translation id="106701514854093668">Žymės staliniame kompiuteryje</translation>
-<translation id="1103523840287552314">Visada versti <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Pritaikyti pagal plotį</translation>
+<translation id="1103523840287552314">Visada versti <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Anuliuoti pertvarkymą</translation>
<translation id="111844081046043029">Ar tikrai norite išeiti iš šio puslapio?</translation>
<translation id="112840717907525620">Gera politikos talpykla</translation>
<translation id="1132774398110320017">„Chrome“ automatinio pildymo nustatymai...</translation>
-<translation id="1152921474424827756">Pasiekite <ph name="BEGIN_LINK"/>talpykloje saugomą <ph name="URL"/> kopiją<ph name="END_LINK"/></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="1152921474424827756">Pasiekite <ph name="BEGIN_LINK" />talpykloje saugomą <ph name="URL" /> kopiją<ph name="END_LINK" /></translation>
+<translation id="121201262018556460">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė nesudėtingą raktą turintį sertifikatą. Užpuolikas galėjo nulaužti privatųjį raktą, o šis serveris gali būti ne tas, kurio tikėjotės (gali būti, kad bendraujate su užpuoliku).</translation>
<translation id="1227224963052638717">Nežinoma politika.</translation>
<translation id="1227633850867390598">Slėpti vertę</translation>
<translation id="1228893227497259893">Netinkamas subjekto identifikatorius</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Registracijos domenas:</translation>
<translation id="1344588688991793829">„Chromium“ automatinio pildymo nustatymai...</translation>
<translation id="1426410128494586442">Taip</translation>
+<translation id="1430915738399379752">Spausdinti</translation>
<translation id="1455235771979731432">Patvirtinant kortelę kilo problema. Patikrinkite interneto ryšį ir bandykite dar kartą.</translation>
<translation id="1491151370853475546">Iš naujo įkelti šį puslapį</translation>
<translation id="1549470594296187301">Norint naudoti šią funkciją, reikia įgalinti „JavaScript“.</translation>
-<translation id="1639239467298939599">Įkeliama</translation>
<translation id="1640180200866533862">Naudotojo politika</translation>
<translation id="1644184664548287040">Tinklo konfigūracija netinkama ir jos neįmanoma importuoti.</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> esančiame puslapyje nurodoma:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi vakar. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar tai tinkama? Jei netinkama, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį.}one{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dieną. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar tai tinkama? Jei netinkama, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį.}few{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dienas. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar tai tinkama? Jei netinkama, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį.}many{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dienos. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar tai tinkama? Jei netinkama, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį.}other{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dienų. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar tai tinkama? Jei netinkama, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį.}}</translation>
+<translation id="168841957122794586">Serverio sertifikate yra nesudėtingas kriptografinis raktas.</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> esančiame puslapyje nurodoma:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas nėra patikimas įrenginio operacinei sistemai. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo.</translation>
<translation id="1821930232296380041">Netinkama užklausa arba jos parametrai</translation>
-<translation id="1853748787962613237">Nepavyko parodyti straipsnio.</translation>
<translation id="1871208020102129563">Įgaliotasis serveris nustatytas naudoti fiksuotų įgaliotųjų serverių, o ne .pac scenarijaus URL.</translation>
-<translation id="1875753206475436906">euristinis tipas: <ph name="HEURISTIC_TYPE"/>
- serverio tipas: <ph name="SERVER_TYPE"/>
- lauko parašas: <ph name="FIELD_SIGNATURE"/>
- formos parašas: <ph name="FORM_SIGNATURE"/>
- eksperimento ID: „<ph name="EXPERIMENT_ID"/>“</translation>
-<translation id="194030505837763158">Apsilankykite <ph name="LINK"/></translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> žymės</translation>
+<translation id="194030505837763158">Apsilankykite <ph name="LINK" /></translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> žymės</translation>
<translation id="1973335181906896915">Serijinio rengimo klaida</translation>
+<translation id="1974060860693918893">Išplėstiniai</translation>
<translation id="2025186561304664664">Nustatytas automatinis įgaliotojo serverio konfigūravimas.</translation>
<translation id="2025623846716345241">Patvirtinti įkėlimą iš naujo</translation>
-<translation id="2030481566774242610">Ar turėjote omenyje <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Ar turėjote omenyje <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Pašto kodas</translation>
<translation id="20817612488360358">Sistemos įgaliotojo serverio nustatymai nustatyti kaip naudotini, bet taip pat nurodyta tiksli įgaliotojo serverio konfigūracija.</translation>
<translation id="2094505752054353250">Domeno neatitikimas</translation>
<translation id="2096368010154057602">Departamentas</translation>
<translation id="2113977810652731515">Kortelė</translation>
-<translation id="2114841414352855701">Nepaisoma, nes buvo pakeista taikant „<ph name="POLICY_NAME"/>“.</translation>
+<translation id="2114841414352855701">Nepaisoma, nes buvo pakeista taikant „<ph name="POLICY_NAME" />“.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Žymės mobiliesiems</translation>
+<translation id="2171101176734966184">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė sertifikatą, kuris pasirašytas naudojant nesudėtingą parašo algoritmą. Tai reiškia, kad serverio pateikti saugos kredencialai galėjo būti suklastoti ir serveris gali būti ne tas, kurio tikėjotės (gali būti, kad bendraujate su užpuoliku).</translation>
<translation id="2181821976797666341">Politika</translation>
<translation id="2212735316055980242">Politika nerasta</translation>
<translation id="2213606439339815911">Gaunami įrašai...</translation>
<translation id="225207911366869382">Pagal šią politiką ši vertė nepatvirtinta.</translation>
<translation id="2262243747453050782">HTTP klaida</translation>
-<translation id="2270192940992995399">Nepavyko rasti straipsnio.</translation>
-<translation id="2328300916057834155">Nepaisoma netinkama žymė indekse <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Nepasiekiami eksperimentai</translation>
+<translation id="229702904922032456">Baigėsi šakninio ar tarpinio sertifikato galiojimas.</translation>
+<translation id="2328300916057834155">Nepaisoma netinkama žymė indekse <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Kitos žymės</translation>
<translation id="2359808026110333948">Tęsti</translation>
<translation id="2367567093518048410">Lygis</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="2396249848217231973">&amp;Anuliuoti ištrynimą</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="2455981314101692989">Šiame tinklalapyje neleidžiamas automatinis šios formos pildymas.</translation>
<translation id="2479410451996844060">Netinkamas paieškos URL.</translation>
+<translation id="2491120439723279231">Serverio sertifikate yra klaidų.</translation>
<translation id="2495083838625180221">JSON analizavimo įrankis</translation>
<translation id="2498091847651709837">Nuskaityti naują kortelę</translation>
<translation id="2556876185419854533">&amp;Anuliuoti redagavimą</translation>
-<translation id="2581221116934462656">Ar norite, kad „<ph name="PRODUCT_NAME"/>“ kitą kartą siūlytų versti šios svetainės puslapius <ph name="LANGUAGE_NAME"/>?</translation>
+<translation id="2581221116934462656">Ar norite, kad „<ph name="PRODUCT_NAME" />“ kitą kartą siūlytų versti šios svetainės puslapius <ph name="LANGUAGE_NAME" />?</translation>
<translation id="2587841377698384444">Katalogo API ID:</translation>
<translation id="2597378329261239068">Šis dokumentas apsaugotas slaptažodžiu. Įveskite slaptažodį.</translation>
+<translation id="2625385379895617796">Jūsų laikrodis skuba</translation>
<translation id="2639739919103226564">Būsena:</translation>
+<translation id="2653659639078652383">Pateikti</translation>
<translation id="2704283930420550640">Vertė neatitinka formato.</translation>
<translation id="2721148159707890343">Užklausa sėkminga</translation>
+<translation id="2728127805433021124">Serverio sertifikatas pasirašytas naudojant nepatikimą parašo algoritmą.</translation>
<translation id="2774256287122201187">Galite tęsti. Jei tęsite veiksmus puslapyje, šis įspėjimas nebus vėl rodomas penkias minutes.</translation>
<translation id="277499241957683684">Trūksta įrenginio įrašo</translation>
<translation id="2835170189407361413">Valyti formą</translation>
-<translation id="2855922900409897335">Patvirtinkite „<ph name="CREDIT_CARD"/>“</translation>
+<translation id="2855922900409897335">Patvirtinkite „<ph name="CREDIT_CARD" />“</translation>
+<translation id="2915500479781995473">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas nebegalioja. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo. Šiuo metu jūsų kompiuterio laikrodis nustatytas į <ph name="CURRENT_TIME" />. Ar tai tinkamas laikas? Jei netinkamas, turėtumėte pakeisti sistemos laikrodžio laiką ir atnaujinti šį puslapį.</translation>
+<translation id="2922350208395188000">Neįmanoma patikrinti serverio sertifikato.</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="2958431318199492670">Tinklo konfigūracija neatitinka ONC standarto. Kai kurių konfigūracijos dalių neįmanoma importuoti.</translation>
<translation id="2972581237482394796">&amp;Atlikti iš naujo</translation>
-<translation id="3010559122411665027">Sąrašo įrašas „<ph name="ENTRY_INDEX"/>“: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Sąrašo įrašas „<ph name="ENTRY_INDEX" />“: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Netinkamas politikos tipas</translation>
<translation id="3105172416063519923">Ištekliaus ID:</translation>
<translation id="3145945101586104090">Iššifruojant atsakymą įvyko klaida</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Sala</translation>
<translation id="3219579145727097045">Įveskite galiojimo pabaigos datą ir 4 skaitmenų kortelės saugos kodą (CVC), nurodytą kortelės priekyje</translation>
-<translation id="3228969707346345236">Išversti nepavyko, nes puslapis jau yra <ph name="LANGUAGE"/>.</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="3228969707346345236">Išversti nepavyko, nes puslapis jau yra <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Anuliuoti pertvarkymą</translation>
+<translation id="3286538390144397061">Paleisti iš naujo dabar</translation>
<translation id="333371639341676808">Neleiskite šiam puslapiui kurti papildomų dialogo langų.</translation>
-<translation id="3369366829301677151">Atnaujinkite ir patvirtinkite „<ph name="CREDIT_CARD"/>“</translation>
+<translation id="3340978935015468852">nustatymų</translation>
+<translation id="3369192424181595722">Laikrodžio klaida</translation>
+<translation id="3369366829301677151">Atnaujinkite ir patvirtinkite „<ph name="CREDIT_CARD" />“</translation>
<translation id="337363190475750230">Teikimas nutrauktas</translation>
<translation id="3377188786107721145">Politikos analizės klaida</translation>
<translation id="3380365263193509176">Nežinoma klaida</translation>
<translation id="3380864720620200369">Kliento ID:</translation>
<translation id="3427342743765426898">&amp;Redaguoti dar kartą</translation>
+<translation id="3435896845095436175">Įgalinti</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Gauti intervalą:</translation>
+<translation id="3462200631372590220">Slėpti išsamią informaciją</translation>
+<translation id="3528171143076753409">Serverio sertifikatas nepatikimas.</translation>
<translation id="3542684924769048008">Slaptažodį naudoti:</translation>
<translation id="3583757800736429874">&amp;Perkelti dar kartą</translation>
<translation id="3623476034248543066">Rodyti vertę</translation>
+<translation id="3648607100222897006">Šios eksperimentinės funkcijos gali bet kada pasikeisti, neveikti ar išnykti. Negarantuojame, kas nutiks, kai įjungsite šiuo eksperimentus. Jūsų naršyklė gali netgi savaime sudegti. Kalbant rimtai, naršyklė gali ištrinti visus duomenis arba jūsų saugumas ir privatumas gali būti pažeisti netikėtais būdais. Visi eksperimentai, kuriuos įgalinsite, bus įgalinti visiems naudotojams. Elkitės atsargiai.</translation>
<translation id="3650584904733503804">Tikrinimas sėkmingas</translation>
<translation id="370665806235115550">Įkeliama...</translation>
<translation id="3712624925041724820">Licencijos baigėsi</translation>
<translation id="3739623965217189342">Nukopijuota nuoroda</translation>
<translation id="375403751935624634">Vertimas nepavyko dėl serverio klaidos.</translation>
<translation id="385051799172605136">Grįžti</translation>
+<translation id="3858027520442213535">Atnaujinti datą ir laiką</translation>
<translation id="3884278016824448484">Nesuderinamas įrenginio identifikatorius</translation>
<translation id="3885155851504623709">Apylinkė</translation>
<translation id="3934680773876859118">Nepavyko įkelti PDF dokumento</translation>
<translation id="3963721102035795474">Skaitytojo režimas</translation>
<translation id="4030383055268325496">&amp;Anuliuoti pridėjimą</translation>
-<translation id="4058922952496707368">Raktas „<ph name="SUBKEY"/>“: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ĮSPĖJIMAS</translation>
+<translation id="4058922952496707368">Raktas „<ph name="SUBKEY" />“: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Įgaliotojo serverio konfigūracijoje nustatyta naudoti .pac scenarijaus URL, o ne fiksuotus įgaliotuosius serverius.</translation>
<translation id="409504436206021213">Neįkelti iš naujo</translation>
<translation id="4103249731201008433">Netinkamas įrenginio serijos numeris</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Netinkamas parašas</translation>
<translation id="4269787794583293679">(Nėra naudotojo vardo)</translation>
<translation id="4300246636397505754">Pasiūlymai tėvams</translation>
-<translation id="4372948949327679948">Numatyta „<ph name="VALUE_TYPE"/>“ vertė.</translation>
+<translation id="4325863107915753736">Nepavyko rasti straipsnio</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="4394049700291259645">Neleisti</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="443673843213245140">Įgaliotojo serverio naudojimas neleidžiamas, bet nurodyta aiški įgaliotojo serverio konfigūracija.</translation>
-<translation id="4506176782989081258">Tikrinimo klaida: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Tikrinimo klaida: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Pašalinti adresą iš „Chrome“?</translation>
<translation id="4594403342090139922">&amp;Anuliuoti ištrynimą</translation>
<translation id="4607653538520819196">Šio puslapio negalima įgalioti naudojant Duomenų taupymo priemonę.</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="4726672564094551039">Iš naujo įkelti politiką</translation>
+<translation id="4728558894243024398">Platforma</translation>
+<translation id="4771973620359291008">Įvyko nežinoma klaida.</translation>
<translation id="4800132727771399293">Patikrinkite kortelės galiojimo pabaigos datą bei saugos kodą (CVC) ir bandykite dar kart</translation>
<translation id="4813512666221746211">Tinklo klaida</translation>
+<translation id="4816492930507672669">Pritaikyti pagal puslapį</translation>
<translation id="4850886885716139402">Žiūrėti</translation>
-<translation id="4923417429809017348">Šis puslapis išverstas iš nežinomos kalbos į <ph name="LANGUAGE_LANGUAGE"/> k.</translation>
+<translation id="4923417429809017348">Šis puslapis išverstas iš nežinomos kalbos į <ph name="LANGUAGE_LANGUAGE" /> k.</translation>
<translation id="4926049483395192435">Turi būti nurodyta.</translation>
<translation id="4968547170521245791">Negalima įgalioti</translation>
-<translation id="498957508165411911">Versti iš <ph name="ORIGINAL_LANGUAGE"/> į <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Versti iš <ph name="ORIGINAL_LANGUAGE" /> į <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Bloga atsarginio atminties įrenginio būsena</translation>
<translation id="5031870354684148875">Apie „Google“ vertėją</translation>
+<translation id="5045550434625856497">Netinkamas slaptažodis</translation>
+<translation id="5087286274860437796">Šiuo metu serverio sertifikatas negalioja.</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="5145883236150621069">Politikos atsakyme yra klaidos kodas</translation>
<translation id="5172758083709347301">Įrenginys</translation>
-<translation id="5179510805599951267">Ne <ph name="ORIGINAL_LANGUAGE"/> k.? Pranešti apie šią klaidą</translation>
+<translation id="5179510805599951267">Ne <ph name="ORIGINAL_LANGUAGE" /> k.? Pranešti apie šią klaidą</translation>
<translation id="5190835502935405962">Žymių juosta</translation>
+<translation id="5199729219167945352">Bandymai</translation>
+<translation id="5251803541071282808">Debesis</translation>
<translation id="5295309862264981122">Patvirtinti naršymą</translation>
<translation id="5299298092464848405">Analizuojant politiką įvyko klaida</translation>
+<translation id="5316812925700871227">Pasukti prieš laikrodžio rodyklę</translation>
<translation id="5317780077021120954">Išsaugoti</translation>
<translation id="536296301121032821">Išsaugant politikos nustatymus įvyko klaida</translation>
-<translation id="5439770059721715174">Schemos patvirtinimo klaida „<ph name="ERROR_PATH"/>“: <ph name="ERROR"/></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="5439770059721715174">Schemos patvirtinimo klaida „<ph name="ERROR_PATH" />“: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Bloga politikos laiko žymė</translation>
<translation id="5470861586879999274">&amp;Redaguoti dar kartą</translation>
<translation id="5509780412636533143">Tvarkomos žymės</translation>
<translation id="5523118979700054094">Politikos pavadinimas</translation>
<translation id="552553974213252141">Ar tekstas tinkamai ištrauktas?</translation>
<translation id="5540224163453853">Nepavyko rasti straipsnio, dėl kurio pateikta užklausa.</translation>
+<translation id="5556459405103347317">Įkelti iš naujo</translation>
<translation id="5565735124758917034">Aktyvus</translation>
<translation id="560412284261940334">Tvarkymas nepalaikomas</translation>
<translation id="5629630648637658800">Įkeliant politikos nustatymus įvyko klaida</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Dabartinis naudotojas</translation>
<translation id="5813119285467412249">&amp;Pridėti dar kartą</translation>
<translation id="5872918882028971132">Pasiūlymai tėvams</translation>
-<translation id="587701087903783706">Uždaryti mobiliesiems skirtą rodinį</translation>
<translation id="59107663811261420">„Google Payments“ nepalaiko šio tipo kortelės naudojantis šio prekybininko paslaugomis. Pasirinkite kitą kortelę.</translation>
+<translation id="5975083100439434680">Tolinti</translation>
<translation id="5989320800837274978">Nenurodyti nei fiksuoti įgaliotieji serveriai, nei .pac scenarijaus URL.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Uždaryti</translation>
+<translation id="6060685159320643512">Atsargiai, šie bandymai gali būti pavojingi</translation>
+<translation id="6151417162996330722">Serverio sertifikato galiojimo laikotarpis per ilgas.</translation>
<translation id="6154808779448689242">Sugrąžintas politikos prieigos raktas neatitinka dabartinio prieigos rakto</translation>
<translation id="6165508094623778733">Sužinokite daugiau</translation>
<translation id="6259156558325130047">&amp;Pertvarkyti dar kartą</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> žymės</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> žymės</translation>
<translation id="6282194474023008486">Pašto kodas</translation>
<translation id="6337534724793800597">Filtruoti politiką pagal pavadinimą</translation>
+<translation id="6387478394221739770">Domina naujos „Chrome“ funkcijos? Išbandykite mūsų beta kanalą adresu chrome.com/beta.</translation>
+<translation id="6426993025560594914">Visi eksperimentai pasiekiami jūsų platformoje.</translation>
<translation id="6445051938772793705">Šalis</translation>
<translation id="6458467102616083041">Nepaisoma, nes numatytoji paieška neleidžiama pagal politiką.</translation>
<translation id="647261751007945333">Įrenginio politika</translation>
<translation id="6512448926095770873">Išeiti iš šio puslapio</translation>
<translation id="6529602333819889595">&amp;Ištrinti dar kartą</translation>
<translation id="6550675742724504774">Parinktys</translation>
-<translation id="6597614308054261376">Bandote pasiekti <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Šiuo metu šio puslapio negalima įgalioti naudojant Duomenų taupymo priemonę.</translation>
-<translation id="6628463337424475685">„<ph name="ENGINE"/>“ paieška</translation>
+<translation id="6597614308054261376">Bandote pasiekti <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Šiuo metu šio puslapio negalima įgalioti naudojant Duomenų taupymo priemonę.</translation>
+<translation id="6628463337424475685">„<ph name="ENGINE" />“ paieška</translation>
<translation id="6644283850729428850">Ši politika nepatvirtinta.</translation>
<translation id="6646897916597483132">Įveskite 4 skaitmenų kortelės saugos kodą (CVC), nurodytą kortelės priekyje</translation>
+<translation id="674375294223700098">Nežinoma serverio sertifikato klaida.</translation>
<translation id="6753269504797312559">Politikos vertė</translation>
<translation id="6831043979455480757">Vertėjas</translation>
<translation id="6839929833149231406">Sritis</translation>
<translation id="6874604403660855544">&amp;Pridėti dar kartą</translation>
<translation id="6891596781022320156">Politikos lygis nepalaikomas.</translation>
<translation id="6915804003454593391">Naudotojas:</translation>
+<translation id="6957887021205513506">Panašu, kad serverio sertifikatas yra suklastotas.</translation>
<translation id="6965382102122355670">Gerai</translation>
<translation id="6965978654500191972">Įrenginys</translation>
<translation id="6970216967273061347">Rajonas</translation>
<translation id="6973656660372572881">Nurodyti fiksuoti įgaliotieji serveriai ir .pac scenarijaus URL.</translation>
<translation id="6980028882292583085">„JavaScript“ įspėjimas</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė sertifikatą, kurio galiojimo laikotarpis per ilgas, kad būtų patikimas.</translation>
<translation id="7087282848513945231">Apygarda</translation>
-<translation id="7108649287766967076">Verčiant į <ph name="TARGET_LANGUAGE"/> įvyko klaida.</translation>
+<translation id="7108649287766967076">Verčiant į <ph name="TARGET_LANGUAGE" /> įvyko klaida.</translation>
<translation id="7139724024395191329">Emyratas</translation>
+<translation id="7179921470347911571">Paleisti iš naujo dabar</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="7186367841673660872">Šis puslapis išverstas iš<ph name="ORIGINAL_LANGUAGE" />į<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Ieškoti <ph name="SITE_NAME"/> pagal <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Ieškoti <ph name="SITE_NAME" /> pagal <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Nepavyksta užmegzti privataus ryšio su <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, nes kompiuterio data ir laikas (<ph name="DATE_AND_TIME" />) yra netinkami.</translation>
<translation id="7275334191706090484">Tvarkomos žymės</translation>
<translation id="7298195798382681320">Rekomenduojama</translation>
<translation id="7334320624316649418">&amp;Pertvarkyti dar kartą</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">„JavaScript“</translation>
<translation id="7537536606612762813">Privaloma</translation>
<translation id="7542995811387359312">Automatinis kredito kortelės informacijos pildymas neleidžiamas, nes šiai formai nenaudojamas saugus ryšys.</translation>
-<translation id="7568593326407688803">Šis puslapis yra<ph name="ORIGINAL_LANGUAGE"/>Ar norėtumėte jį išversti?</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="7568593326407688803">Šis puslapis yra<ph name="ORIGINAL_LANGUAGE" />Ar norėtumėte jį išversti?</translation>
<translation id="7569952961197462199">Pašalinti kredito kortelės informaciją iš „Chrome“?</translation>
-<translation id="7600965453749440009">Niekada neversti <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Vertė nepatenka į diapazoną <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Serverio sertifikatas pažeidžia pavadinimų apribojimus.</translation>
+<translation id="7600965453749440009">Niekada neversti <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Vertė nepatenka į diapazoną <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Domina naujos „Chrome“ funkcijos? Išbandykite mūsų kuriamą kanalą adresu chrome.com/dev.</translation>
<translation id="7752995774971033316">Netvarkoma</translation>
+<translation id="7761701407923456692">Serverio sertifikatas neatitinka URL.</translation>
<translation id="777702478322588152">Prefektūra</translation>
<translation id="7791543448312431591">Pridėti</translation>
<translation id="7805768142964895445">Būsena</translation>
<translation id="7813600968533626083">Pašalinti formos pasiūlymą iš „Chrome“?</translation>
<translation id="7887683347370398519">Patikrinkite kortelės saugos kodą (CVC) ir bandykite dar kartą</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Serverio sertifikatas dar negalioja.</translation>
<translation id="7956713633345437162">Žymės mobiliesiems</translation>
<translation id="7961015016161918242">Niekada</translation>
<translation id="7977590112176369853">&lt;enter query&gt;</translation>
-<translation id="7983301409776629893">Visada versti iš <ph name="ORIGINAL_LANGUAGE"/> į <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Visada versti iš <ph name="ORIGINAL_LANGUAGE" /> į <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Žymės staliniame kompiuteryje</translation>
<translation id="7995512525968007366">Nenurodytas</translation>
-<translation id="8034522405403831421">Šis puslapis yra <ph name="SOURCE_LANGUAGE"/> k. Išversti į <ph name="TARGET_LANGUAGE"/> k.?</translation>
+<translation id="8003882219468422867">Nepaisymas įmonės lygiu</translation>
+<translation id="8034522405403831421">Šis puslapis yra <ph name="SOURCE_LANGUAGE" /> k. Išversti į <ph name="TARGET_LANGUAGE" /> k.?</translation>
<translation id="8088680233425245692">Nepavyko peržiūrėti straipsnio.</translation>
<translation id="8091372947890762290">Laukiama aktyvinimo serveryje</translation>
<translation id="8194797478851900357">&amp;Anuliuoti perkėlimą</translation>
-<translation id="8201077131113104583">Netinkamas plėtinio, kurio ID „<ph name="EXTENSION_ID"/>“, atnaujinimo URL.</translation>
+<translation id="8201077131113104583">Netinkamas plėtinio, kurio ID „<ph name="EXTENSION_ID" />“, atnaujinimo URL.</translation>
<translation id="8208216423136871611">Neišsaugoti</translation>
<translation id="8218327578424803826">Priskirta vieta:</translation>
<translation id="8249320324621329438">Paskutinį kartą gauta:</translation>
+<translation id="8294431847097064396">Šaltinis</translation>
<translation id="8308427013383895095">Vertimas nepavyko dėl tinklo ryšio problemos.</translation>
<translation id="8311778656528046050">Ar tikrai norite iš naujo įkelti šį puslapį?</translation>
<translation id="8349305172487531364">Žymių juosta</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Taikoma</translation>
<translation id="8530504477309582336">„Google Payments“ nepalaiko šio tipo kortelės. Pasirinkite kitą kortelę.</translation>
<translation id="8553075262323480129">Išversti negalima, nes nepavyko nustatyti puslapio kalbos.</translation>
-<translation id="8571890674111243710">Puslapis verčiamas į <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Nepavyksta užmegzti privataus ryšio su <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, nes įrenginio data ir laikas (<ph name="DATE_AND_TIME" />) yra netinkami.</translation>
+<translation id="8571890674111243710">Puslapis verčiamas į <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Viską nustatyti į numatytuosius nustatymus</translation>
<translation id="8713130696108419660">Netinkamas pradinis parašas</translation>
<translation id="8725066075913043281">Bandyti dar kartą</translation>
+<translation id="8738058698779197622">Jei norite užmegzti saugų ryšį, turėsite tinkamai nustatyti laikrodį. To reikalaujama todėl, kad svetainių tapatybei įrodyti naudojami sertifikatai galioja tik tam tikrą laikotarpį. Kadangi įrenginio laikrodis nustatytas netinkamai, „Chromium“ negali tinkamai patvirtinti sertifikatų.</translation>
<translation id="8790007591277257123">&amp;Ištrinti dar kartą</translation>
<translation id="8804164990146287819">Privatumo politika</translation>
+<translation id="8820817407110198400">Žymės</translation>
<translation id="8824019021993735287">Šiuo metu „Chrome“ negali patvirtinti jūsų kortelės. Bandykite dar kartą vėliau.</translation>
<translation id="8834246243508017242">Įgalinti automatinį pildymą naudojant kontaktus…</translation>
<translation id="883848425547221593">Kitos žymės</translation>
+<translation id="884923133447025588">Nerasta atšaukimo mechanizmo.</translation>
<translation id="8866481888320382733">Analizuojant politikos nustatymus įvyko klaida</translation>
<translation id="8876793034577346603">Analizuojant tinklo konfigūraciją įvyko klaida.</translation>
<translation id="8891727572606052622">Netinkamas įgaliotojo serverio režimas.</translation>
-<translation id="8940229512486821554">Paleisti „<ph name="EXTENSION_NAME"/>“ komandą: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Deja, šis eksperimentas negalimas platformoje.</translation>
+<translation id="8903921497873541725">Artinti</translation>
+<translation id="8932102934695377596">Jūsų laikrodis atsilieka</translation>
+<translation id="8940229512486821554">Paleisti „<ph name="EXTENSION_NAME" />“ komandą: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Baigėsi serverio sertifikato galiojimo laikas.</translation>
<translation id="8988760548304185580">Įveskite galiojimo pabaigos datą ir 3 skaitmenų kortelės saugos kodą (CVC), nurodytą kitoje kortelės pusėje</translation>
-<translation id="9020542370529661692">Šis puslapis išverstas į <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Visoje sistemoje taikomas žymas gali nustatyti tik savininkas: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Šis puslapis išverstas į <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė neteisingą sertifikatą.</translation>
<translation id="9125941078353557812">Įveskite 3 skaitmenų kortelės saugos kodą (CVC), nurodytą kitoje kortelės pusėje</translation>
<translation id="9137013805542155359">Rodyti originalą</translation>
<translation id="9148507642005240123">&amp;Anuliuoti redagavimą</translation>
<translation id="9154176715500758432">Likti šiame puslapyje</translation>
<translation id="9170848237812810038">&amp;Atšaukti</translation>
+<translation id="917450738466192189">Serverio sertifikatas negalioja.</translation>
+<translation id="9187827965378254003">Deja, atrodo, kad šiuo metų nėra galimų bandymų.</translation>
<translation id="9207861905230894330">Nepavyko pridėti straipsnio.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">CLEAR FORM</translation>
+<translation id="988159990683914416">Vykdymo programa sukurta</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_lv.xtb b/chromium/components/strings/components_strings_lv.xtb
index 3d2f9ea85e6..be6d2e6275d 100644
--- a/chromium/components/strings/components_strings_lv.xtb
+++ b/chromium/components/strings/components_strings_lv.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="lv">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="lv">
+<translation id="1032854598605920125">Pagriezt pulksteņrādītāju kustības virzienā</translation>
<translation id="1055184225775184556">&amp;Pievienošanas atsaukšana</translation>
<translation id="106701514854093668">Datora grāmatzīmes</translation>
-<translation id="1103523840287552314">Vienmēr tulkot <ph name="LANGUAGE"/> valodas saturu</translation>
+<translation id="1080116354587839789">Ietilpināt pēc platuma</translation>
+<translation id="1103523840287552314">Vienmēr tulkot <ph name="LANGUAGE" /> valodas saturu</translation>
<translation id="1113869188872983271">&amp;Atsaukt pārkārtošanu</translation>
<translation id="111844081046043029">Vai jūs tiešām vēlaties pamest šo lapu?</translation>
<translation id="112840717907525620">Politikas kešatmiņa ir labā stāvoklī.</translation>
<translation id="1132774398110320017">Chrome automātiskās aizpildes iestatījumi...</translation>
-<translation id="1152921474424827756">Piekļūstiet vietnes <ph name="URL"/> <ph name="BEGIN_LINK"/>kešatmiņā saglabātajai kopijai<ph name="END_LINK"/></translation>
+<translation id="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="1152921474424827756">Piekļūstiet vietnes <ph name="URL" /> <ph name="BEGIN_LINK" />kešatmiņā saglabātajai kopijai<ph name="END_LINK" /></translation>
+<translation id="121201262018556460">Jūs centāties sasniegt <ph name="DOMAIN" />, bet servera uzrādītais sertifikāts satur vāju atslēgu. Iespējams, uzbrucējs ir uzlauzis privāto atslēgu un serveris var nebūt tas, ko centāties sasniegt (iespējams, jūs sazināties ar uzbrucēju).</translation>
<translation id="1227224963052638717">Nezināma politika.</translation>
<translation id="1227633850867390598">Slēpt vērtību</translation>
<translation id="1228893227497259893">Nepareizs vienības identifikators</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Reģistrācijas domēns:</translation>
<translation id="1344588688991793829">Chromium automātiskās aizpildes iestatījumi...</translation>
<translation id="1426410128494586442">Jā</translation>
+<translation id="1430915738399379752">Drukāt</translation>
<translation id="1455235771979731432">Verificējot jūsu karti, radās problēma. Pārbaudiet interneta savienojumu un mēģiniet vēlreiz.</translation>
<translation id="1491151370853475546">Atkārtoti ielādēt šo lapu</translation>
<translation id="1549470594296187301">Lai izmantotu šo funkciju, ir jābūt iespējotai valodai JavaScript.</translation>
-<translation id="1639239467298939599">Notiek ielāde</translation>
<translation id="1640180200866533862">Lietotāja politikas</translation>
<translation id="1644184664548287040">Tīkla konfigurācija nav derīga, un to nevarēja importēt.</translation>
-<translation id="1693754753824026215">Lapa vietnē <ph name="SITE"/> saka:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Šis serveris nevarēja pierādīt, ka ir <ph name="DOMAIN" />; tā drošības sertifikāta derīguma termiņš beidzās vakar. Šī problēma var rasties nepareizas konfigurācijas dēļ vai tādēļ, ka kāds uzbrucējs ir pārtvēris jūsu savienojumu. Jūsu datora pulkstenī pašlaik ir iestatīts šāds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistēmas pulksteni un pēc tam atsvaidziniet šo lapu.}zero{Šis serveris nevarēja pierādīt, ka ir <ph name="DOMAIN" />; tā drošības sertifikāta derīguma termiņš beidzās pirms # dienām. Šī problēma var rasties nepareizas konfigurācijas dēļ vai tādēļ, ka kāds uzbrucējs ir pārtvēris jūsu savienojumu. Jūsu datora pulkstenī pašlaik ir iestatīts šāds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistēmas pulksteni un pēc tam atsvaidziniet šo lapu.}one{Šis serveris nevarēja pierādīt, ka ir <ph name="DOMAIN" />; tā drošības sertifikāta derīguma termiņš beidzās pirms # dienas. Šī problēma var rasties nepareizas konfigurācijas dēļ vai tādēļ, ka kāds uzbrucējs ir pārtvēris jūsu savienojumu. Jūsu datora pulkstenī pašlaik ir iestatīts šāds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistēmas pulksteni un pēc tam atsvaidziniet šo lapu.}other{Šis serveris nevarēja pierādīt, ka ir <ph name="DOMAIN" />; tā drošības sertifikāta derīguma termiņš beidzās pirms # dienām. Šī problēma var rasties nepareizas konfigurācijas dēļ vai tādēļ, ka kāds uzbrucējs ir pārtvēris jūsu savienojumu. Jūsu datora pulkstenī pašlaik ir iestatīts šāds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistēmas pulksteni un pēc tam atsvaidziniet šo lapu.}}</translation>
+<translation id="168841957122794586">Servera sertifikāts ietver vāju kriptogrāfisko atslēgu.</translation>
+<translation id="1693754753824026215">Lapa vietnē <ph name="SITE" /> saka:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Šis serveris nevarēja pierādīt, ka šī ir vietne <ph name="DOMAIN" />; tās drošības sertifikāts netiek uzskatīts par uzticamu jūsu ierīces operētājsistēmā. Iespējams, tas ir nepareizas konfigurācijas dēļ vai arī kāds ir ļaunprātīgi izmantojis jūsu savienojumu.</translation>
<translation id="1821930232296380041">Pieprasījums vai tā parametri nebija derīgi.</translation>
-<translation id="1853748787962613237">Rakstu neizdevās parādīt.</translation>
<translation id="1871208020102129563">Starpniekserveris ir iestatīts, lai tas lietotu fiksētus starpniekserverus, nevis .pac skripta URL.</translation>
-<translation id="1875753206475436906">heristiskais tips: <ph name="HEURISTIC_TYPE"/>
- servera tips: <ph name="SERVER_TYPE"/>
- lauka paraksts: <ph name="FIELD_SIGNATURE"/>
- veidlapas paraksts: <ph name="FORM_SIGNATURE"/>
- eksperimenta ID: <ph name="EXPERIMENT_ID"/></translation>
-<translation id="194030505837763158">Apmeklējiet vietni <ph name="LINK"/></translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> grāmatzīmes</translation>
+<translation id="194030505837763158">Apmeklējiet vietni <ph name="LINK" /></translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> grāmatzīmes</translation>
<translation id="1973335181906896915">Radās serializēšanas kļūda.</translation>
+<translation id="1974060860693918893">Papildu</translation>
<translation id="2025186561304664664">Starpniekserverim ir iestatīta autokonfigurācija.</translation>
<translation id="2025623846716345241">Atkārtotas ielādes apstiprināšana</translation>
-<translation id="2030481566774242610">Vai domājāt <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Vai domājāt <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Pasta indekss</translation>
<translation id="20817612488360358">Ir iestatīta datora starpniekserveru iestatījumu lietošana, bet ir norādīta arī atklāta starpniekservera konfigurācija.</translation>
<translation id="2094505752054353250">Domēni nesaskan</translation>
<translation id="2096368010154057602">Departaments</translation>
<translation id="2113977810652731515">Karte</translation>
-<translation id="2114841414352855701">Ignorēta, jo to atcēla politika <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Ignorēta, jo to atcēla politika <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Mobilās grāmatzīmes</translation>
+<translation id="2171101176734966184">Jūs mēģinājāt sasniegt domēnu <ph name="DOMAIN" />, bet serveris uzrādīja sertifikātu, kas ir parakstīts, izmantojot vāju paraksta algoritmu. Tas nozīmē, ka servera norādītie drošības akreditācijas dati var būt viltoti un šis serveris var nebūt tas serveris, kuru mēģināt sasniegt (iespējams, jūs sazināties ar uzbrucēju).</translation>
<translation id="2181821976797666341">Politikas</translation>
<translation id="2212735316055980242">Politika netika atrasta.</translation>
<translation id="2213606439339815911">Notiek ierakstu ienešana...</translation>
<translation id="225207911366869382">Šī vērtība vairs netiek atbalstīta šai politikai.</translation>
<translation id="2262243747453050782">HTTP kļūda</translation>
-<translation id="2270192940992995399">Rakstu neizdevās atrast.</translation>
-<translation id="2328300916057834155">Nederīga grāmatzīme ignorēta <ph name="ENTRY_INDEX"/>. rādītājā</translation>
+<translation id="2282872951544483773">Nepieejamie eksperimenti</translation>
+<translation id="229702904922032456">Saknes sertifikāts vai starpnieksertifikāts vairs nav derīgs.</translation>
+<translation id="2328300916057834155">Nederīga grāmatzīme ignorēta <ph name="ENTRY_INDEX" />. rādītājā</translation>
<translation id="2354001756790975382">Citas grāmatzīmes</translation>
<translation id="2359808026110333948">Turpināt</translation>
<translation id="2367567093518048410">Līmenis</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="2396249848217231973">&amp;Atsaukt dzēšanu</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="2455981314101692989">Šajā tīmekļa lapā ir atspējota šīs veidlapas automātiskā aizpilde.</translation>
<translation id="2479410451996844060">Nederīgs meklēšanas URL.</translation>
+<translation id="2491120439723279231">Servera sertifikātā ir kļūdas.</translation>
<translation id="2495083838625180221">JSON parsētājs</translation>
<translation id="2498091847651709837">Skenēt jaunu karti</translation>
<translation id="2556876185419854533">&amp;Labojuma atsaukšana</translation>
-<translation id="2581221116934462656">Vai vēlaties, lai <ph name="PRODUCT_NAME"/> nākamreiz piedāvātu tulkot šīs vietnes lapas, kuru saturs ir šādā valodā: <ph name="LANGUAGE_NAME"/>?</translation>
+<translation id="2581221116934462656">Vai vēlaties, lai <ph name="PRODUCT_NAME" /> nākamreiz piedāvātu tulkot šīs vietnes lapas, kuru saturs ir šādā valodā: <ph name="LANGUAGE_NAME" />?</translation>
<translation id="2587841377698384444">Direktorija API ID:</translation>
<translation id="2597378329261239068">Šis dokuments ir aizsargāts ar paroli. Lūdzu, ievadiet paroli.</translation>
+<translation id="2625385379895617796">Norādītais laiks ir pārāk tālu nākotnē</translation>
<translation id="2639739919103226564">Statuss:</translation>
+<translation id="2653659639078652383">Iesniegt</translation>
<translation id="2704283930420550640">Vērtība neatbilst formātam.</translation>
<translation id="2721148159707890343">Pieprasījums bija veiksmīgs.</translation>
+<translation id="2728127805433021124">Servera sertifikāts ir parakstīts, izmantojot vāju paraksta algoritmu.</translation>
<translation id="2774256287122201187">Jūs varat turpināt. Ja turpināsiet lietot lapu, šis brīdinājums netiks rādīts vēlreiz piecas minūtes.</translation>
<translation id="277499241957683684">Trūkst ierīces ieraksta.</translation>
<translation id="2835170189407361413">Notīrīt veidlapu</translation>
-<translation id="2855922900409897335">Verificējiet kredītkarti <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Verificējiet kredītkarti <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Šis serveris nevarēja pierādīt, ka ir <ph name="DOMAIN" />; tā drošības sertifikāts vairs nav derīgs. Šī problēma var rasties nepareizas konfigurācijas dēļ vai tādēļ, ka kāds uzbrucējs ir pārtvēris jūsu savienojumu. Jūsu datora pulkstenī pašlaik ir iestatīts šāds datums: <ph name="CURRENT_TIME" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistēmas pulksteni un pēc tam atsvaidziniet šo lapu.</translation>
+<translation id="2922350208395188000">Servera sertifikātu nevar pārbaudīt.</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="2958431318199492670">Tīkla konfigurācija neatbilst standartam ONC. Iespējams, konfigurācijas daļas netiks importētas.</translation>
<translation id="2972581237482394796">&amp;Pāratsaukt</translation>
-<translation id="3010559122411665027">Saraksta ieraksts “<ph name="ENTRY_INDEX"/>”: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Saraksta ieraksts “<ph name="ENTRY_INDEX" />”: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Politikas tips nav pareizs.</translation>
<translation id="3105172416063519923">Līdzekļa ID:</translation>
<translation id="3145945101586104090">Neizdevās atšifrēt atbildi.</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Sala</translation>
<translation id="3219579145727097045">Ievadiet derīguma termiņu un 4 ciparu CVC kodu, kas ir norādīts jūsu kredītkartes priekšpusē.</translation>
-<translation id="3228969707346345236">Tulkošana neizdevās, jo lapa jau ir <ph name="LANGUAGE"/> valodā.</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="3228969707346345236">Tulkošana neizdevās, jo lapa jau ir <ph name="LANGUAGE" /> valodā.</translation>
<translation id="3270847123878663523">&amp;Pārkārtošanas atsaukšana</translation>
+<translation id="3286538390144397061">Restartēt tūlīt</translation>
<translation id="333371639341676808">Neļaujiet šai lapai veidot papildu dialogus.</translation>
-<translation id="3369366829301677151">Atjauniniet un verificējiet kredītkartes <ph name="CREDIT_CARD"/> informāciju</translation>
+<translation id="3340978935015468852">Iestatījumi</translation>
+<translation id="3369192424181595722">Pulksteņa kļūda</translation>
+<translation id="3369366829301677151">Atjauniniet un verificējiet kredītkartes <ph name="CREDIT_CARD" /> informāciju</translation>
<translation id="337363190475750230">Tika noņemta piekļuve</translation>
<translation id="3377188786107721145">Radās politikas parsēšanas kļūda.</translation>
<translation id="3380365263193509176">Nezināma kļūda</translation>
<translation id="3380864720620200369">Klienta ID:</translation>
<translation id="3427342743765426898">&amp;Labojuma atsaukuma atcelšana</translation>
+<translation id="3435896845095436175">Iespējot</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Pirmsielādes intervāls:</translation>
+<translation id="3462200631372590220">Slēpt papildu informāciju</translation>
+<translation id="3528171143076753409">Servera sertifikāts nav uzticams.</translation>
<translation id="3542684924769048008">Izmantot paroli:</translation>
<translation id="3583757800736429874">&amp;Pārvietošanas atsaukuma atcelšana</translation>
<translation id="3623476034248543066">Rādīt vērtību</translation>
+<translation id="3648607100222897006">Šīs eksperimentālās funkcijas jebkurā laikā var mainīties, pārstāt darboties vai pazust. Mēs nesniedzam pilnīgi nekādas garantijas tam, kas var notikt, ja jūs ieslēdzat vienu no šiem eksperimentiem. Jūsu pārlūks var pat sabrukt. Nopietni runājot, pārlūks var izdzēst visus jūsu datus vai arī neparedzamā veidā var tikt pārkāpti drošības un konfidencialitātes noteikumi. Visi jūsu aktivizētie eksperimenti tiks aktivizēti visiem šī pārlūka lietotājiem. Lūdzu, esiet uzmanīgs!</translation>
<translation id="3650584904733503804">Validācija bija veiksmīga.</translation>
<translation id="370665806235115550">Notiek ielāde...</translation>
<translation id="3712624925041724820">Nav pietiekami daudz licenču.</translation>
<translation id="3739623965217189342">Jūsu kopētā saite</translation>
<translation id="375403751935624634">Tulkojums neizdevās servera kļūdas dēļ.</translation>
<translation id="385051799172605136">Atpakaļ</translation>
+<translation id="3858027520442213535">Atjaunināt datumu un laiku</translation>
<translation id="3884278016824448484">Ierīces identifikators rada konfliktu.</translation>
<translation id="3885155851504623709">Pagasts</translation>
<translation id="3934680773876859118">Neizdevās ielādēt PDF dokumentu</translation>
<translation id="3963721102035795474">Lasītāja režīms</translation>
<translation id="4030383055268325496">&amp;Atsaukt pievienošanu</translation>
-<translation id="4058922952496707368">Atslēga <ph name="SUBKEY"/>: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">BRĪDINĀJUMS</translation>
+<translation id="4058922952496707368">Atslēga <ph name="SUBKEY" />: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Starpniekserveris ir iestatīts, lai tas lietotu .pac skripta URL, nevis fiksētus starpniekserverus.</translation>
<translation id="409504436206021213">Neielādēt atkārtoti</translation>
<translation id="4103249731201008433">Ierīces sērijas numurs nav derīgs.</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Paraksts nav derīgs.</translation>
<translation id="4269787794583293679">(Nav lietotājvārda)</translation>
<translation id="4300246636397505754">Vecāku ieteikumi</translation>
-<translation id="4372948949327679948">Tika gaidīta vērtība <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Rakstu neizdevās atrast.</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="4394049700291259645">Atspējot</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="443673843213245140">Starpniekservera lietošana ir atspējota, bet ir norādīta atklāta starpniekservera konfigurācija.</translation>
-<translation id="4506176782989081258">Validācijas kļūda: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Validācijas kļūda: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Vai noņemt adresi no pārlūka Chrome?</translation>
<translation id="4594403342090139922">&amp;Dzēšanas atsaukšana</translation>
<translation id="4607653538520819196">Datu lietojuma samazinātājs nevar apstrādāt šo lapu, izmantojot starpniekserveri.</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="4726672564094551039">Atkārtoti ielādēt politikas</translation>
+<translation id="4728558894243024398">Platforma</translation>
+<translation id="4771973620359291008">Radās nezināma kļūda.</translation>
<translation id="4800132727771399293">Pārbaudiet derīguma termiņu un CVC kodu un mēģiniet vēlreiz.</translation>
<translation id="4813512666221746211">Tīkla kļūda</translation>
+<translation id="4816492930507672669">Ietilpināt lapā</translation>
<translation id="4850886885716139402">Skatīt</translation>
-<translation id="4923417429809017348">Šī lapa ir tulkota no nezināmas valodas valodā: <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Šī lapa ir tulkota no nezināmas valodas valodā: <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Jābūt norādītai.</translation>
<translation id="4968547170521245791">Nevar apstrādāt, izmantojot starpniekserveri</translation>
-<translation id="498957508165411911">Vai tulkot no <ph name="ORIGINAL_LANGUAGE"/> valodas <ph name="TARGET_LANGUAGE"/> valodā?</translation>
+<translation id="498957508165411911">Vai tulkot no <ph name="ORIGINAL_LANGUAGE" /> valodas <ph name="TARGET_LANGUAGE" /> valodā?</translation>
<translation id="5019198164206649151">Dublējumu krātuve nav labā stāvoklī.</translation>
<translation id="5031870354684148875">Par Google tulkotāju</translation>
+<translation id="5045550434625856497">Nepareiza parole</translation>
+<translation id="5087286274860437796">Servera sertifikāts šobrīd nav derīgs.</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="5145883236150621069">Politikas atbildē ir kļūdas kods.</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="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="5199729219167945352">Eksperimenti</translation>
+<translation id="5251803541071282808">Mākonis</translation>
<translation id="5295309862264981122">Apstiprināt navigāciju</translation>
<translation id="5299298092464848405">Parsējot politiku, radās kļūda.</translation>
+<translation id="5316812925700871227">Pagriezt pretēji pulksteņrādītāju kustības virzienam</translation>
<translation id="5317780077021120954">Saglabāt</translation>
<translation id="536296301121032821">Neizdevās saglabāt politikas iestatījumus.</translation>
-<translation id="5439770059721715174">Šeit tika atklāta shēmas validēšanas kļūda: <ph name="ERROR_PATH"/>. Kļūdas ziņojums: <ph name="ERROR"/>.</translation>
+<translation id="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="5439770059721715174">Šeit tika atklāta shēmas validēšanas kļūda: <ph name="ERROR_PATH" />. Kļūdas ziņojums: <ph name="ERROR" />.</translation>
<translation id="5455374756549232013">Politikas laikspiedols nav derīgs.</translation>
<translation id="5470861586879999274">&amp;Atcelt labojuma atsaukšanu</translation>
<translation id="5509780412636533143">Pārvaldītās grāmatzīmes</translation>
<translation id="5523118979700054094">Politikas nosaukums</translation>
<translation id="552553974213252141">Vai iegūtais teksts bija pareizs?</translation>
<translation id="5540224163453853">Pieprasīto rakstu nevarēja atrast.</translation>
+<translation id="5556459405103347317">Pārlādēt</translation>
<translation id="5565735124758917034">Aktīvs</translation>
<translation id="560412284261940334">Pārvaldīšana netiek atbalstīta.</translation>
<translation id="5629630648637658800">Neizdevās ielādēt politikas iestatījumus.</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Pašreizējais lietotājs</translation>
<translation id="5813119285467412249">&amp;Pievienošanas atsaukuma atcelšana</translation>
<translation id="5872918882028971132">Vecāku ieteikumi</translation>
-<translation id="587701087903783706">Aizvērt mobilajām ierīcēm piemēroto skatījumu</translation>
<translation id="59107663811261420">Šis kartes veids šim tirgotājam pakalpojumā Google Payments netiek atbalstīts. Lūdzu, atlasiet citu karti.</translation>
+<translation id="5975083100439434680">Tālināt</translation>
<translation id="5989320800837274978">Nav norādīti nedz fiksēti starpniekserveri, nedz .pac skripta URL.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Aizvērt</translation>
+<translation id="6060685159320643512">Esiet uzmanīgs! Šie eksperimenti var jums kaitēt</translation>
+<translation id="6151417162996330722">Šī servera sertifikāta derīguma periods ir pārāk ilgs.</translation>
<translation id="6154808779448689242">Atgrieztais politikas marķieris neatbilst pašreizējam marķierim.</translation>
<translation id="6165508094623778733">Uzziniet vairāk</translation>
<translation id="6259156558325130047">&amp;Pārkārtošanas atsaukuma atcelšana</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> grāmatzīmes</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> grāmatzīmes</translation>
<translation id="6282194474023008486">Pasta indekss</translation>
<translation id="6337534724793800597">Filtrēt politikas pēc nosaukuma</translation>
+<translation id="6387478394221739770">Vai jūs interesē jaunas Chrome funkcijas? Izmēģiniet mūsu Beta versiju, kas pieejama vietnē chrome.com/beta.</translation>
+<translation id="6426993025560594914">Jūsu platformā ir pieejami visi eksperimenti!</translation>
<translation id="6445051938772793705">Valsts</translation>
<translation id="6458467102616083041">Ignorēta, jo ar politiku ir atspējota noklusējuma meklēšana.</translation>
<translation id="647261751007945333">Ierīces politikas</translation>
<translation id="6512448926095770873">Pamest šo lapu</translation>
<translation id="6529602333819889595">&amp;Dzēšanas atsaukuma atcelšana</translation>
<translation id="6550675742724504774">Opcijas</translation>
-<translation id="6597614308054261376">Jūs mēģināt atvērt vietni <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Pašlaik datu lietojuma samazinātājs nevar apstrādāt šo lapu, izmantojot starpniekserveri.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> meklēšana</translation>
+<translation id="6597614308054261376">Jūs mēģināt atvērt vietni <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Pašlaik datu lietojuma samazinātājs nevar apstrādāt šo lapu, izmantojot starpniekserveri.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> meklēšana</translation>
<translation id="6644283850729428850">Šī politika ir izbeigta.</translation>
<translation id="6646897916597483132">Ievadiet 4 ciparu CVC kodu, kas norādīts jūsu kredītkartes priekšpusē.</translation>
+<translation id="674375294223700098">Nezināma servera sertifikāta kļūda.</translation>
<translation id="6753269504797312559">Politikas vērtība</translation>
<translation id="6831043979455480757">Tulkot</translation>
<translation id="6839929833149231406">Apgabals</translation>
<translation id="6874604403660855544">&amp;Atcelt pievienošanas atsaukšanu</translation>
<translation id="6891596781022320156">Politikas līmenis netiek atbalstīts.</translation>
<translation id="6915804003454593391">Lietotājs:</translation>
+<translation id="6957887021205513506">Šķiet, ka servera sertifikāts ir viltojums.</translation>
<translation id="6965382102122355670">Labi</translation>
<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="6980028882292583085">JavaScript trauksme</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Jūs mēģinājāt sasniegt domēnu <ph name="DOMAIN" />, bet serveris uzrādīja sertifikātu, kura derīguma periods ir pārāk ilgs, lai būtu uzticams.</translation>
<translation id="7087282848513945231">Grāfiste</translation>
-<translation id="7108649287766967076">Neizdevās tulkot šādā valodā: <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="7108649287766967076">Neizdevās tulkot šādā valodā: <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="7139724024395191329">Emirāts</translation>
+<translation id="7179921470347911571">Restartēt tūlīt</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="7186367841673660872">Šī lapa ir tulkota no<ph name="ORIGINAL_LANGUAGE" />valodas<ph name="LANGUAGE_LANGUAGE" />valodā</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Meklēt<ph name="SITE_NAME"/> <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Meklēt<ph name="SITE_NAME" /> <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Nevar izveidot privātu savienojumu ar <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, jo jūsu datora datums un laiks (<ph name="DATE_AND_TIME" />) nav pareizs.</translation>
<translation id="7275334191706090484">Pārvaldītās grāmatzīmes</translation>
<translation id="7298195798382681320">Ieteicams</translation>
<translation id="7334320624316649418">&amp;Atcelt pārkārtošanas atsaukšanu</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obligāti</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="7568593326407688803">Šī lapa ir rakstīta<ph name="ORIGINAL_LANGUAGE"/>valodā. Vai vēlaties to tulkot?</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="7568593326407688803">Šī lapa ir rakstīta<ph name="ORIGINAL_LANGUAGE" />valodā. Vai vēlaties to tulkot?</translation>
<translation id="7569952961197462199">Vai noņemt kredītkarti no pārlūka Chrome?</translation>
-<translation id="7600965453749440009">Nekad netulkot saturu, kas rakstīts <ph name="LANGUAGE"/> valodā</translation>
-<translation id="7610193165460212391">Vērtība pārsniedz diapazonu: <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Servera sertifikātā ir pārkāpti nosaukuma ierobežojumi.</translation>
+<translation id="7600965453749440009">Nekad netulkot saturu, kas rakstīts <ph name="LANGUAGE" /> valodā</translation>
+<translation id="7610193165460212391">Vērtība pārsniedz diapazonu: <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Vai jūs interesē jaunas Chrome funkcijas? Izmēģiniet izstrādātāja versiju vietnē chrome.com/dev.</translation>
<translation id="7752995774971033316">Netiek pārvaldīts</translation>
+<translation id="7761701407923456692">Servera sertifikāts neatbilst URL.</translation>
<translation id="777702478322588152">Prefektūra</translation>
<translation id="7791543448312431591">Pievienot</translation>
<translation id="7805768142964895445">Statuss</translation>
<translation id="7813600968533626083">Vai noņemt veidlapas ieteikumu no pārlūka Chrome?</translation>
<translation id="7887683347370398519">Pārbaudiet CVC kodu un mēģiniet vēlreiz.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Servera sertifikāts vēl nav apstiprināts.</translation>
<translation id="7956713633345437162">Mobilās grāmatzīmes</translation>
<translation id="7961015016161918242">Nekad</translation>
<translation id="7977590112176369853">&lt;ievadīt vaicājumu&gt;</translation>
-<translation id="7983301409776629893">Vienmēr tulkot no <ph name="ORIGINAL_LANGUAGE"/> valodas <ph name="TARGET_LANGUAGE"/> valodā</translation>
+<translation id="7983301409776629893">Vienmēr tulkot no <ph name="ORIGINAL_LANGUAGE" /> valodas <ph name="TARGET_LANGUAGE" /> valodā</translation>
<translation id="7988324688042446538">Datora grāmatzīmes</translation>
<translation id="7995512525968007366">Nav norādīts</translation>
-<translation id="8034522405403831421">Šī lapas saturs ir šādā valodā: <ph name="SOURCE_LANGUAGE"/>. Vai tulkot šādā valodā: <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Ignorēšana: uzņēmuma politika</translation>
+<translation id="8034522405403831421">Šī lapas saturs ir šādā valodā: <ph name="SOURCE_LANGUAGE" />. Vai tulkot šādā valodā: <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Rakstu neizdevās skatīt.</translation>
<translation id="8091372947890762290">Aktivizācija vēl nav apstiprināta serverī.</translation>
<translation id="8194797478851900357">&amp;Pārvietošanas atsaukšana</translation>
-<translation id="8201077131113104583">Nederīgs atjaunināšanas URL paplašinājumam ar ID “<ph name="EXTENSION_ID"/>”.</translation>
+<translation id="8201077131113104583">Nederīgs atjaunināšanas URL paplašinājumam ar ID “<ph name="EXTENSION_ID" />”.</translation>
<translation id="8208216423136871611">Nesaglabāt</translation>
<translation id="8218327578424803826">Piešķirtā atrašanās vieta:</translation>
<translation id="8249320324621329438">Pēdējās pirmsielādes laiks:</translation>
+<translation id="8294431847097064396">Avots</translation>
<translation id="8308427013383895095">Tulkošana neizdevās, jo radās problēma ar tīkla savienojumu.</translation>
<translation id="8311778656528046050">Vai jūs tiešām vēlaties atkārtoti ielādēt šo lapu?</translation>
<translation id="8349305172487531364">Grāmatzīmju josla</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Attiecas uz</translation>
<translation id="8530504477309582336">Šis kartes veids netiek atbalstīts pakalpojumā Google Payments. Lūdzu, atlasiet citu karti.</translation>
<translation id="8553075262323480129">Tulkošana neizdevās, jo lapas valoda nav nosakāma.</translation>
-<translation id="8571890674111243710">Notiek lapas tulkošana uz <ph name="LANGUAGE"/> valodu...</translation>
+<translation id="8559762987265718583">Nevar izveidot privātu savienojumu ar <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, jo jūsu ierīces datums un laiks (<ph name="DATE_AND_TIME" />) nav pareizs.</translation>
+<translation id="8571890674111243710">Notiek lapas tulkošana uz <ph name="LANGUAGE" /> valodu...</translation>
+<translation id="8647750283161643317">Atiestatīt visiem to noklusējuma iestatījumus</translation>
<translation id="8713130696108419660">Nederīgs sākotnējais paraksts</translation>
<translation id="8725066075913043281">Mēģināt vēlreiz</translation>
+<translation id="8738058698779197622">Lai izveidotu drošu savienojumu, ir jāiestata pareizs pulksteņa laiks. Tas ir nepieciešams, jo sertifikāti, kurus vietnes izmanto, lai tiktu identificētas, ir derīgi tikai noteiktos laika periodos. Tā kā jūsu ierīces pulkstenis nav pareizi iestatīts, Chromium nevar verificēt šos sertifikātus.</translation>
<translation id="8790007591277257123">&amp;Atcelt dzēšanas atsaukšanu</translation>
<translation id="8804164990146287819">Konfidencialitātes politika</translation>
+<translation id="8820817407110198400">Grāmatzīmes</translation>
<translation id="8824019021993735287">Pārlūks Chrome pašlaik nevarēja verificēt jūsu karti. Lūdzu, vēlāk mēģiniet vēlreiz.</translation>
<translation id="8834246243508017242">Iespējot automātisko aizpildi, izmantojot kontaktpersonas...</translation>
<translation id="883848425547221593">Citas grāmatzīmes</translation>
+<translation id="884923133447025588">Nav atrasts atsaukšanas mehānisms.</translation>
<translation id="8866481888320382733">Parsējot politikas iestatījumus, radās kļūda.</translation>
<translation id="8876793034577346603">Neizdevās parsēt tīkla konfigurāciju.</translation>
<translation id="8891727572606052622">Nederīgs starpniekservera režīms.</translation>
-<translation id="8940229512486821554">Izpildīt <ph name="EXTENSION_NAME"/> komandu: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Diemžēl šis eksperiments nav pieejams jūsu platformā.</translation>
+<translation id="8903921497873541725">Tuvināt</translation>
+<translation id="8932102934695377596">Norādītais laiks ir pārāk tālu pagātnē</translation>
+<translation id="8940229512486821554">Izpildīt <ph name="EXTENSION_NAME" /> komandu: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Servera sertifikātam ir beidzies derīguma termiņš.</translation>
<translation id="8988760548304185580">Ievadiet derīguma termiņu un 3 ciparu CVC kodu, kas ir norādīts jūsu kredītkartes aizmugurē.</translation>
-<translation id="9020542370529661692">Šī lapa ir tulkota <ph name="TARGET_LANGUAGE"/> valodā.</translation>
+<translation id="901974403500617787">Atzīmes, kas attiecas uz visu sistēmu, var iestatīt tikai īpašnieks: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Šī lapa ir tulkota <ph name="TARGET_LANGUAGE" /> valodā.</translation>
+<translation id="9049981332609050619">Jūs centāties piekļūt <ph name="DOMAIN" />, bet serveris piedāvāja nederīgu sertifikātu.</translation>
<translation id="9125941078353557812">Ievadiet 3 ciparu CVC kodu, kas norādīts jūsu kredītkartes aizmugurē.</translation>
<translation id="9137013805542155359">Rādīt oriģinālo</translation>
<translation id="9148507642005240123">&amp;Atsaukt labojumu</translation>
<translation id="9154176715500758432">Palikt šajā lapā</translation>
<translation id="9170848237812810038">&amp;Atsaukt</translation>
+<translation id="917450738466192189">Servera sertifikāts ir nederīgs.</translation>
+<translation id="9187827965378254003">Izskatās, ka pašlaik nav pieejams neviens eksperiments.</translation>
<translation id="9207861905230894330">Rakstu neizdevās pievienot.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">NOTĪRĪT VEIDLAPU</translation>
+<translation id="988159990683914416">Attīstītāja konstrukcija</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ml.xtb b/chromium/components/strings/components_strings_ml.xtb
index 77c088f899c..52c4a78f48f 100644
--- a/chromium/components/strings/components_strings_ml.xtb
+++ b/chromium/components/strings/components_strings_ml.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ml">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ml">
+<translation id="1032854598605920125">ഘടികാരദിശയിൽ‌ തിരിക്കുക</translation>
<translation id="1055184225775184556">&amp;ചേർക്കുന്നത് പഴയപടിയാക്കുക</translation>
<translation id="106701514854093668">ഡെസ്‌ക്‌ടോപ്പ് ബുക്ക്‌മാർക്കുകൾ</translation>
-<translation id="1103523840287552314"><ph name="LANGUAGE"/> എല്ലായ്പ്പോഴും വിവര്‍ത്തനം ചെയ്യുക </translation>
+<translation id="1080116354587839789">അനുയോജ്യമായ വീതിയിലാക്കുക</translation>
+<translation id="1103523840287552314"><ph name="LANGUAGE" /> എല്ലായ്പ്പോഴും വിവര്‍ത്തനം ചെയ്യുക </translation>
<translation id="1113869188872983271">&amp;പുനഃക്രമീകരിക്കുന്നത് പഴയപടിയാക്കുക</translation>
<translation id="111844081046043029">നിങ്ങള്‍ക്ക് ഈ പേജ് ഉപേക്ഷിക്കുന്നതിന് താല്പര്യമുണ്ടോ?</translation>
<translation id="112840717907525620">നയ കാഷെ ശരി</translation>
<translation id="1132774398110320017">Chrome ഓട്ടോഫിൽ ക്രമീകരണങ്ങൾ...</translation>
-<translation id="1152921474424827756"><ph name="URL"/>-ന്റെ <ph name="BEGIN_LINK"/>കാഷെ ചെയ്‌ത പകർപ്പ്<ph name="END_LINK"/> ആക്‌സസ്സുചെയ്യുക</translation>
+<translation id="1150979032973867961">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷ സർട്ടിഫിക്കറ്റിനെ നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ ഓപ്പറേറ്റിംഗ് സിസ്‌റ്റത്തിന് പരിചയമില്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
+<translation id="1152921474424827756"><ph name="URL" />-ന്റെ <ph name="BEGIN_LINK" />കാഷെ ചെയ്‌ത പകർപ്പ്<ph name="END_LINK" /> ആക്‌സസ്സുചെയ്യുക</translation>
+<translation id="121201262018556460">നിങ്ങള്‍‌ <ph name="DOMAIN" /> എന്നതില്‍ എത്താന്‍‌ ശ്രമിച്ചു, പക്ഷെ സെർവർ ഹാജരാക്കിയ സർട്ടിഫിക്കറ്റിൽ ഒരു ദുർബലമായ കീ ഉൾപ്പെടുന്നു. ഒരു ആക്രമണകാരിക്ക് സ്വകാര്യ കീ നശിപ്പിച്ചിരിക്കാം, കൂടാതെ സെർവർ നിങ്ങൾ പ്രതീക്ഷിച്ച സെർവർ ആയിരിക്കില്ല (നിങ്ങൾ ആശയവിനിമയം നടത്തുന്നത് ഒരു ആക്രമണകാരിയുമായിട്ടാകാം).</translation>
<translation id="1227224963052638717">അറിയപ്പെടാത്ത നയം.</translation>
<translation id="1227633850867390598">മൂല്യം മറയ്‌ക്കുക</translation>
<translation id="1228893227497259893">തെറ്റായ എന്റിറ്റി ഐഡന്റിഫയർ</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">എൻറോൾമെന്റ് ഡൊമെയ്ൻ:</translation>
<translation id="1344588688991793829">Chromium ഓട്ടോഫിൽ ക്രമീകരണങ്ങൾ...</translation>
<translation id="1426410128494586442">അതെ</translation>
+<translation id="1430915738399379752">അച്ചടിക്കുക</translation>
<translation id="1455235771979731432">നിങ്ങളുടെ കാർഡ് പരിശോധിച്ചുറപ്പിക്കുന്നതിൽ ഒരു പ്രശ്‌നമുണ്ടായിരുന്നു. ഇന്റർ‌നെറ്റ് കണക്ഷൻ പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക.</translation>
<translation id="1491151370853475546">ഈ പേജ് വീണ്ടും ലോഡുചെയ്യുക</translation>
<translation id="1549470594296187301">ഈ ഫീച്ചർ ഉപയോഗിക്കാൻ JavaScript പ്രവർത്തനക്ഷമമാക്കിയിരിക്കണം.</translation>
-<translation id="1639239467298939599">ലോഡുചെയ്യുന്നു</translation>
<translation id="1640180200866533862">ഉപയോക്തൃ നയങ്ങൾ</translation>
<translation id="1644184664548287040">നെറ്റ്‌വർക്ക് കോൺഫിഗറേഷൻ അസാധുവായതിനാൽ ഇമ്പോർട്ടുചെയ്യാൻ കഴിഞ്ഞില്ല.</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> ലെ പേജ് പറയുന്നത്:</translation>
+<translation id="1655462015569774233">{1,plural, =1{ഈ സെർവറിന് ഇത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് ഇന്നലെ കാലഹരണപ്പെട്ടു. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു ആക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്. നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ ക്ലോക്ക് നിലവിൽ <ph name="CURRENT_DATE" /> എന്ന് സജ്ജമാക്കി. അത് ശരിയാണോ? അല്ലെങ്കിൽ, നിങ്ങൾ സിസ്റ്റത്തിന്റെ ക്ലോക്ക് ശരിയാക്കി ഈ പേജ് പുതുക്കുക.}other{ഈ സെർവറിന് ഇത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; ഇതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് # ദിവസം മുമ്പ് കാലഹരണപ്പെട്ടു. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു ആക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്. നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ ക്ലോക്ക് നിലവിൽ <ph name="CURRENT_DATE" /> എന്ന് സജ്ജമാക്കി. അത് ശരിയാണോ? അല്ലെങ്കിൽ, നിങ്ങൾ സിസ്റ്റത്തിന്റെ ക്ലോക്ക് ശരിയാക്കി ഈ പേജ് പുതുക്കുക.}}</translation>
+<translation id="168841957122794586">സെർവർ സർട്ടിഫിക്കറ്റിൽ ഒരു ദുർബലമായ ഗൂഢഭാഷ കീ ഉൾപ്പെടുന്നു.</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> ലെ പേജ് പറയുന്നത്:</translation>
+<translation id="1706954506755087368">{1,plural, =1{ഈ സെർവറിന് ഇത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് ഇന്നലെ മുതൽ സാധുവല്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു ആക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.}other{ഈ സെർവറിന് ഇത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് # ദിവസം മുതൽ സാധുവായിരിക്കില്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു ആക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷ സർട്ടിഫിക്കറ്റിനെ നിങ്ങളുടെ ഉപകരണത്തിന്റെ ഓപ്പറേറ്റിംഗ് സിസ്‌റ്റത്തിന് പരിചയമില്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
<translation id="1821930232296380041">അഭ്യർത്ഥന അല്ലെങ്കിൽ അഭ്യർത്ഥന പാരാമീറ്ററുകൾ അസാധുവാണ്</translation>
-<translation id="1853748787962613237">ലേഖനം പ്രദർശിപ്പിക്കുന്നത് പരാജയപ്പെട്ടു.</translation>
<translation id="1871208020102129563">സ്ഥിരമായ പ്രോക്‌സി സെർവറുകൾ ഉപയോഗിക്കുന്നതിനായി പ്രോക്‌സി സജ്ജീകരിച്ചിരിക്കുന്നു, ഒരു .pac സ്‌ക്രിപ്റ്റ് URL ഉപയോഗിക്കുന്നതിനല്ല.</translation>
-<translation id="1875753206475436906">ഹ്യൂറുസ്‌റ്റിക് തരം: <ph name="HEURISTIC_TYPE"/>
- സെർവർ തരം: <ph name="SERVER_TYPE"/>
- ഫീൽഡ് സിഗ്നേച്ചർ: <ph name="FIELD_SIGNATURE"/>
- ഫോം സിഗ്നേച്ചർ: <ph name="FORM_SIGNATURE"/>
- പരീക്ഷണ ഐഡി: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158"><ph name="LINK"/>-ലേക്ക് പോകുക</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> ബുക്ക്‌മാർക്കുകൾ</translation>
+<translation id="194030505837763158"><ph name="LINK" />-ലേക്ക് പോകുക</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> ബുക്ക്‌മാർക്കുകൾ</translation>
<translation id="1973335181906896915">സീരിയലൈസേഷൻ പിശക്</translation>
+<translation id="1974060860693918893">നൂതനം</translation>
<translation id="2025186561304664664">പ്രോക്സി യാന്ത്രികമായി കോൺഫിഗർ ചെയ്യാൻ സജ്ജമാക്കി.</translation>
<translation id="2025623846716345241">വീണ്ടും ലോഡുചെയ്യുന്നത് സ്ഥിരീകരിക്കുക</translation>
-<translation id="2030481566774242610">നിങ്ങൾ ഉദ്ദേശിച്ചത് <ph name="LINK"/> ആണോ?</translation>
+<translation id="2030481566774242610">നിങ്ങൾ ഉദ്ദേശിച്ചത് <ph name="LINK" /> ആണോ?</translation>
<translation id="2053553514270667976">തപാൽ കോഡ്</translation>
<translation id="20817612488360358">സിസ്റ്റം പ്രോക്‌സി ക്രമീകരണം ഉപയോഗിക്കുന്നതിനായി സജ്ജമാക്കി, പക്ഷെ ഒരു സ്‌പഷ്‌ടമായ പ്രോക്‌സി കോൺഫിഗറേഷനും അതോടൊപ്പം നിർദ്ദേശിച്ചിരിക്കുന്നു.</translation>
<translation id="2094505752054353250">ഡൊമെയ്‌ൻ പൊരുത്തമില്ലായ്‌മ</translation>
<translation id="2096368010154057602">വകുപ്പ്</translation>
<translation id="2113977810652731515">കാർഡ്</translation>
-<translation id="2114841414352855701"> <ph name="POLICY_NAME"/> എന്നതിനാൽ മറികടന്നതിനാൽ ഇത് അവഗണിച്ചു.</translation>
+<translation id="2114841414352855701"> <ph name="POLICY_NAME" /> എന്നതിനാൽ മറികടന്നതിനാൽ ഇത് അവഗണിച്ചു.</translation>
+<translation id="2128531968068887769">നേറ്റീവ് ക്ലയന്‍റ്</translation>
<translation id="213826338245044447">മൊബൈൽ ബുക്ക്‌മാർക്കുകൾ</translation>
+<translation id="2171101176734966184">നിങ്ങള്‍‌ <ph name="DOMAIN" /> എന്നതില്‍ എത്താന്‍‌ ശ്രമിച്ചു, പക്ഷേ ഒരു ദുർബലമായ സിഗ്‌നേച്ചര്‍‌ അല്‍‌ഗോരിതം ഉപയോഗിച്ച് ഒപ്പിട്ട ഒരു സര്‍‌ട്ടിഫിക്കറ്റ് സെര്‍‌വര്‍‌ നല്‍‌കി. ഇതിനര്‍‌ത്ഥം സെര്‍‌വര്‍‌ നല്‍‌കിയ സുരക്ഷാ ക്രെഡന്‍‌ഷ്യലുകള്‍‌ വ്യാജമാകാമെന്നും സെര്‍‌വര്‍‌ നിങ്ങള്‍‌ ഉദ്ദേശിച്ച സെര്‍‌വറായിരിക്കില്ലെന്നുമാണ് (നിങ്ങള്‍‌ ആക്രമണകാരിയുമായിട്ടാകാം ആശയവിനിമയം നടത്തുന്നത്).</translation>
<translation id="2181821976797666341">നയങ്ങൾ</translation>
<translation id="2212735316055980242">നയം കണ്ടെത്തിയില്ല</translation>
<translation id="2213606439339815911">എൻട്രികൾ ലഭ്യമാക്കുന്നു...</translation>
<translation id="225207911366869382">ഈ നയത്തിനായി ഈ മൂല്യത്തെ ഒഴിവാക്കി.</translation>
<translation id="2262243747453050782">HTTP പിശക്</translation>
-<translation id="2270192940992995399">ലേഖനം കണ്ടെത്തുന്നത് പരാജയപ്പെട്ടു.</translation>
-<translation id="2328300916057834155"><ph name="ENTRY_INDEX"/> സൂചികയിൽ അസാധുവായ ബുക്ക്‌മാർക്ക് അവഗണിച്ചു</translation>
+<translation id="2282872951544483773">ലഭ്യമല്ലാത്ത പരീക്ഷണങ്ങൾ</translation>
+<translation id="229702904922032456">ഒരു റൂട്ട് അല്ലെങ്കിൽ ഇന്റർമീഡിയറ്റ് സർട്ടിഫിക്കറ്റ് കാലഹരണപ്പെട്ടു.</translation>
+<translation id="2328300916057834155"><ph name="ENTRY_INDEX" /> സൂചികയിൽ അസാധുവായ ബുക്ക്‌മാർക്ക് അവഗണിച്ചു</translation>
<translation id="2354001756790975382">മറ്റ് ബുക്‌മാര്‍ക്കുകള്‍</translation>
<translation id="2359808026110333948">തുടരൂ</translation>
<translation id="2367567093518048410">നില</translation>
+<translation id="2384307209577226199">എന്റര്‍പ്രൈസ് ഡിഫോൾട്ട്</translation>
+<translation id="2386255080630008482">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് അസാധുവാക്കി.</translation>
<translation id="2392959068659972793">മൂല്യമൊന്നും സജ്ജമാക്കാത്ത നയങ്ങൾ കാണിക്കുക</translation>
<translation id="2396249848217231973">&amp;ഇല്ലാതാക്കൽ പഴയപടിയാക്കുക</translation>
+<translation id="2413528052993050574">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; സെർവറിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് റദ്ദാക്കിയിരിക്കാം. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
<translation id="2455981314101692989">ഈ വെബ്പേജ് ഈ ഫോമിനായുള്ള സ്വപ്രേരിത ഫില്ലിംഗിനെ അപ്രാപ്തമാക്കി.</translation>
<translation id="2479410451996844060">തിരയൽ URL അസാധുവാണ്.</translation>
+<translation id="2491120439723279231">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റില്‍ പിശകുകള്‍ അടങ്ങിയിരിക്കുന്നു.</translation>
<translation id="2495083838625180221">JSON പാഴ്‌സർ</translation>
<translation id="2498091847651709837">പുതിയ കാർഡ് സ്‌കാൻ ചെയ്യുക</translation>
<translation id="2556876185419854533">&amp;എഡിറ്റുചെയ്യുന്നത് പഴയപടിയാക്കുക</translation>
-<translation id="2581221116934462656">അടുത്ത തവണ ഈ സൈറ്റിൽ നിന്ന് <ph name="LANGUAGE_NAME"/> പേജുകൾ വിവർത്തനം ചെയ്യാനായി <ph name="PRODUCT_NAME"/> ഓഫർ ചെയ്യുന്നതിൽ നിങ്ങൾക്ക് താൽപ്പര്യമുണ്ടോ?</translation>
+<translation id="2581221116934462656">അടുത്ത തവണ ഈ സൈറ്റിൽ നിന്ന് <ph name="LANGUAGE_NAME" /> പേജുകൾ വിവർത്തനം ചെയ്യാനായി <ph name="PRODUCT_NAME" /> ഓഫർ ചെയ്യുന്നതിൽ നിങ്ങൾക്ക് താൽപ്പര്യമുണ്ടോ?</translation>
<translation id="2587841377698384444">ഡയറക്‌ടറി API ഐഡി:</translation>
<translation id="2597378329261239068">ഈ പ്രമാണം പാസ്‌വേഡ് പരിരക്ഷിതമാണ്. ദയവായി ഒരു പാസ്‌വേഡ് നല്‍‌കുക.</translation>
+<translation id="2625385379895617796">നിങ്ങളുടെ ക്ലോക്ക് വളരെ മുമ്പിലാണ്</translation>
<translation id="2639739919103226564">നില:</translation>
+<translation id="2653659639078652383">സമര്‍പ്പിക്കൂ</translation>
<translation id="2704283930420550640">മൂല്യം ഫോർമാറ്റുമായി പൊരുത്തപ്പെടുന്നില്ല.</translation>
<translation id="2721148159707890343">അഭ്യർത്ഥന വിജയിച്ചു</translation>
+<translation id="2728127805433021124">ഒരു ദുര്‍ബ്ബല സിഗ്നേച്ചര്‍ അല്‍ഗോരിതം ഉപയോഗിച്ചുകൊണ്ട് സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് ഒപ്പുവച്ചു.</translation>
<translation id="2774256287122201187">നിങ്ങൾക്ക് തുടരാം. പേജിൽ തുടരുകയാണെങ്കിൽ, അഞ്ച് മിനിറ്റിന് ഈ മുന്നറിയിപ്പ് വീണ്ടും ദൃശ്യമാകുന്നതല്ല.</translation>
<translation id="277499241957683684">ഉപകരണ റെക്കോർഡ് കാണുന്നില്ല</translation>
<translation id="2835170189407361413">ഫോം മായ്‌ക്കുക</translation>
-<translation id="2855922900409897335">നിങ്ങളുടെ <ph name="CREDIT_CARD"/> പരിശോധിച്ചുറപ്പിക്കുക</translation>
+<translation id="2855922900409897335">നിങ്ങളുടെ <ph name="CREDIT_CARD" /> പരിശോധിച്ചുറപ്പിക്കുക</translation>
+<translation id="2915500479781995473">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു ആക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നതിനാലോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്. നിലവിൽ നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ സമയം <ph name="CURRENT_TIME" /> എന്നായി സജ്ജീകരിച്ചിരിക്കുന്നു. അത് ശരിയല്ലേ? ശരിയല്ലെങ്കിൽ, സിസ്‌റ്റത്തിന്റെ സമയം ശരിയാക്കിയതിനുശേഷം ഈ പേജ് പുതുക്കുക.</translation>
+<translation id="2922350208395188000">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് പരിശോധിക്കാന്‍ കഴിയില്ല.</translation>
+<translation id="2941952326391522266">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; <ph name="DOMAIN2" /> എന്നതിൽ നിന്നുള്ളതാണ് അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ്. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
<translation id="2958431318199492670">നെറ്റ്‌വർക്ക് കോൺഫിഗറേഷൻ ONC സ്റ്റാൻഡേർഡിന് അനുസൃതമായി പ്രവർത്തിക്കുന്നില്ല. കോൺഫിഗറേഷൻ ഭാഗങ്ങൾ ഇമ്പോർട്ടുചെയ്‌തേക്കില്ല.</translation>
<translation id="2972581237482394796">&amp;വീണ്ടും ചെയ്യുക</translation>
-<translation id="3010559122411665027">ലിസ്റ്റ് എൻട്രി &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">ലിസ്റ്റ് എൻട്രി "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">തെറ്റായ നയ തരം</translation>
<translation id="3105172416063519923">അസറ്റ് ഐഡി:</translation>
<translation id="3145945101586104090">പ്രതികരണം ഡീകോഡ് ചെയ്യുന്നത് പരാജയപ്പെട്ടു</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">ഐലന്‍ഡ്</translation>
<translation id="3219579145727097045">നിങ്ങളുടെ കാർഡിന്റെ മുന്നിലുള്ള കാലഹരണപ്പെടൽ തീയതിയും 4-അക്ക CVC-യും നൽകുക</translation>
-<translation id="3228969707346345236"><ph name="LANGUAGE"/> ല്‍‌ ഈ പേജ് ഇതിനകം ഉള്ളതിനാല്‍‌ വിവര്‍‌ത്തനം പരാജയപ്പെട്ടു.</translation>
+<translation id="3225919329040284222">ബിൽട്ട്-ഇൻ പ്രതീക്ഷകള്‍ക്ക് പൊരുത്തപ്പെടാത്ത സര്‍ട്ടിഫിക്കറ്റാണ് സെര്‍വര്‍ അവതരിപ്പിച്ചത്. നിങ്ങളെ സംരക്ഷിക്കുന്നതിലേക്കായുള്ള നിശ്ചിത, ഉന്നത-സുരക്ഷാ വെബ്‌സൈറ്റുകൾക്കായാണ് ഈ പ്രതീക്ഷകൾ ഉൾപ്പെടുത്തിയിരിക്കുന്നത്.</translation>
+<translation id="3228969707346345236"><ph name="LANGUAGE" /> ല്‍‌ ഈ പേജ് ഇതിനകം ഉള്ളതിനാല്‍‌ വിവര്‍‌ത്തനം പരാജയപ്പെട്ടു.</translation>
<translation id="3270847123878663523">&amp;പുനഃക്രമീകരിക്കുന്നത് പഴയപടിയാക്കുക</translation>
+<translation id="3286538390144397061">ഇപ്പോള്‍ പുനരാരംഭിക്കുക</translation>
<translation id="333371639341676808">അധികമുള്ള ഡയലോഗുകള്‍ സൃഷ്ടിക്കുന്നതില്‍ നിന്ന് ഈ പേജിനെ തടയൂ.</translation>
-<translation id="3369366829301677151">അപ്‌ഡേറ്റുചെയ്‌ത് നിങ്ങളുടെ <ph name="CREDIT_CARD"/> പരിശോധിച്ചുറപ്പിക്കുക</translation>
+<translation id="3340978935015468852">ക്രമീകരണങ്ങൾ</translation>
+<translation id="3369192424181595722">ക്ലോക്കിലെ പിശക്</translation>
+<translation id="3369366829301677151">അപ്‌ഡേറ്റുചെയ്‌ത് നിങ്ങളുടെ <ph name="CREDIT_CARD" /> പരിശോധിച്ചുറപ്പിക്കുക</translation>
<translation id="337363190475750230">ഡിപ്രൊവിഷൻ ചെയ്‌തു</translation>
<translation id="3377188786107721145">നയം പാഴ്‌സുചെയ്യുന്നതിൽ പിശക്</translation>
<translation id="3380365263193509176">അജ്ഞാതമായ പിശക്</translation>
<translation id="3380864720620200369">ക്ലയന്റ് ID:</translation>
<translation id="3427342743765426898">&amp;എഡിറ്റുചെയ്യുന്നത് വീണ്ടും ചെയ്യുക</translation>
+<translation id="3435896845095436175">തയ്യാറാക്കുക</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">ഇടവേള ലഭ്യമാക്കുക:</translation>
+<translation id="3462200631372590220">വിപുലമായവ മറയ്ക്കുക</translation>
+<translation id="3528171143076753409">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് വിശ്വാസയോഗ്യമല്ല.</translation>
<translation id="3542684924769048008">ഇതിനായി പാസ്‌വേഡ് ഉപയോഗിക്കുക:</translation>
<translation id="3583757800736429874">&amp;നീക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="3623476034248543066">മൂല്യം കാണിക്കുക</translation>
+<translation id="3648607100222897006">ഈ പരീക്ഷണ സവിശേഷതകൾ ഏത് സമയത്തും മാറുകയോ തകരാറിലാകുകയോ അപ്രത്യക്ഷമാവുകയോ ചെയ്യാം. നിങ്ങൾ ഈ പരീക്ഷണങ്ങളിലൊന്ന് ഓൺ ചെയ്താൽ എന്ത് സംഭവിക്കുമെന്നത് സംബന്ധിച്ച് ഞങ്ങൾ പൂർണ്ണമായ ഒരു ഉറപ്പും നൽകില്ല, മാത്രമല്ല നിങ്ങളുടെ ബ്രൌസർ ആക്സ്മികമായി തകരാറിലാകുക പോലും ചെയ്തേക്കാം. തമാശ നിർത്തൂ, നിങ്ങളുടെ എല്ലാ ഡാറ്റയെയും ബ്രൌസർ ഇല്ലാതാക്കിയേക്കാം, അല്ലെങ്കിൽ നിങ്ങളുടെ സുരക്ഷയും സ്വകാര്യതയും അപ്രതീക്ഷിതമായ രീതിയിൽ തകരാറിലായേക്കാം. നിങ്ങൾ പ്രാപ്തമാക്കുന്ന ഏത് പരീക്ഷണങ്ങളും ഈ ബ്രൗസറിന്റെ എല്ലാ ഉപയോക്താക്കൾക്കുമായി പ്രാപ്തമാക്കിയിരിക്കും. ദയവായി ശ്രദ്ധയോടെ തുടരുക.</translation>
<translation id="3650584904733503804">മൂല്യനിർണ്ണയം വിജയകരം</translation>
<translation id="370665806235115550">ലോഡ്ചെയ്യുന്നു...</translation>
<translation id="3712624925041724820">ലൈസൻസുകൾ കാലഹരണപ്പെട്ടു</translation>
<translation id="3739623965217189342">നിങ്ങൾ പകർത്തിയ ലിങ്ക്</translation>
<translation id="375403751935624634">ഒരു സെര്‍വര്‍ പിശക് കാരണം വിവര്‍‌ത്തനം പരാജയപ്പെട്ടു.</translation>
<translation id="385051799172605136">പിന്നോട്ട്</translation>
+<translation id="3858027520442213535">തീയതിയും സമയവും അപ്‌ഡേറ്റുചെയ്യുക</translation>
<translation id="3884278016824448484">വിരുദ്ധ ഉപകരണ ഐഡന്റിഫയർ</translation>
<translation id="3885155851504623709">പാരിഷ്</translation>
<translation id="3934680773876859118">PDF പ്രമാണം ലോഡുചെയ്യുന്നത് പരാജയപ്പെട്ടു</translation>
<translation id="3963721102035795474">റീഡർ മോഡ്</translation>
<translation id="4030383055268325496">&amp;ചേർക്കുന്നത് പഴയപടിയാക്കുക</translation>
-<translation id="4058922952496707368">കീ &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">മുന്നറിയിപ്പ്</translation>
+<translation id="4058922952496707368">കീ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">പ്രോക്‌സി കോൺഫിഗറേഷൻ .pac സ്‌ക്രിപ്റ്റ് URL ഉപയോഗിക്കുന്നതിനായി സജ്ജീകരിച്ചിരിക്കുന്നു, സ്ഥിരമായ പ്രോക്‌സി സെർവറുകൾ ഉപയോഗിക്കുന്നതിനായല്ല.</translation>
<translation id="409504436206021213">വീണ്ടും ലോഡുചെയ്യരുത്</translation>
<translation id="4103249731201008433">ഉപകരണ സീരിയൽ നമ്പർ അസാധുവാണ്</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">മോശം സിഗ്‌നേച്ചർ</translation>
<translation id="4269787794583293679">(ഉപയോക്തൃനാമമില്ല)</translation>
<translation id="4300246636397505754">പാരന്റ് നിർദ്ദേശങ്ങൾ</translation>
-<translation id="4372948949327679948">പ്രതീക്ഷിച്ച <ph name="VALUE_TYPE"/> മൂല്യം.</translation>
+<translation id="4325863107915753736">ലേഖനം കണ്ടെത്തുന്നത് പരാജയപ്പെട്ടു</translation>
+<translation id="4372948949327679948">പ്രതീക്ഷിച്ച <ph name="VALUE_TYPE" /> മൂല്യം.</translation>
+<translation id="4377125064752653719">നിങ്ങള്‍‌ <ph name="DOMAIN" /> എന്നതില്‍‌ എത്താന്‍‌ ശ്രമിച്ചു, പക്ഷേ സെര്‍‌വര്‍‌ നൽകിയ സര്‍‌ട്ടിഫിക്കറ്റ് അത് നല്‍‌കിയ ആള്‍‌ അസാധുവാക്കി. സെര്‍‌വര്‍‌ നല്‍‌കിയ സുരക്ഷാ ക്രെഡന്‍‌ഷ്യലുകള്‍‌ തികച്ചും വിശ്വാ‍സയോഗ്യമല്ല എന്നാണ് ഇതിനര്‍‌ത്ഥം. നിങ്ങള്‍‌ ഒരു ആക്രമണകാരിയുമായിട്ടാകാം ആശയവിനിമയം നടത്തുന്നത്.</translation>
+<translation id="4394049700291259645">അപ്രാപ്‌തമാക്കുക</translation>
+<translation id="4424024547088906515">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് Chrome-ന് പരിചയമില്ലാത്തതാണ്. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
<translation id="443673843213245140">പ്രോക്‌സി ഉപയോഗം അപ്രാപ്‌തമാക്കി പക്ഷെ ഒരു വ്യക്തമായ പ്രോക്‌സി കോൺഫിഗറേഷൻ നിർദ്ദേശിച്ചു.</translation>
-<translation id="4506176782989081258">മൂല്യനിർണ്ണയ പിശക്: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">മൂല്യനിർണ്ണയ പിശക്: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chrome-ൽ നിന്ന് വിലാസം നീക്കംചെയ്യണോ?</translation>
<translation id="4594403342090139922">&amp;ഇല്ലാതാക്കുന്നത് പഴയപടിയാക്കുക</translation>
<translation id="4607653538520819196">ഡാറ്റ സേവർ വഴി ഈ പേജ് പ്രോക്‌സി ചെയ്യാനാവില്ല.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റിൽ പിശകുകൾ അടങ്ങിയിരിക്കുന്നു. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
<translation id="4726672564094551039">നയങ്ങൾ വീണ്ടും ലോഡുചെയ്യുക</translation>
+<translation id="4728558894243024398">പ്ലാറ്റ്ഫോം</translation>
+<translation id="4771973620359291008">ഒരു അജ്ഞാത പിശക് സംഭവിച്ചു.</translation>
<translation id="4800132727771399293">നിങ്ങളുടെ കാലഹരണ തീയതിയും CVC യും പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക</translation>
<translation id="4813512666221746211">നെറ്റ്‌വര്‍ക്ക് പിശക്</translation>
+<translation id="4816492930507672669">പേജിന് യുക്തമാക്കുക</translation>
<translation id="4850886885716139402">കാണുക</translation>
-<translation id="4923417429809017348">ഈ പേജിനെ അറിയപ്പെടാത്ത ഒരു ഭാഷയില്‍‌ നിന്നും <ph name="LANGUAGE_LANGUAGE"/> എന്നതിലേക്ക് വിവര്‍‌ത്തനം ചെയ്തു</translation>
+<translation id="4923417429809017348">ഈ പേജിനെ അറിയപ്പെടാത്ത ഒരു ഭാഷയില്‍‌ നിന്നും <ph name="LANGUAGE_LANGUAGE" /> എന്നതിലേക്ക് വിവര്‍‌ത്തനം ചെയ്തു</translation>
<translation id="4926049483395192435">വ്യക്തമാക്കേണ്ടതാണ്.</translation>
<translation id="4968547170521245791">പ്രോക്‌സി ചെയ്യാനാകില്ല</translation>
-<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE"/>-ൽ നിന്ന് <ph name="TARGET_LANGUAGE"/>-ലേക്ക് വിവർത്തനം ചെയ്യണോ?</translation>
+<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE" />-ൽ നിന്ന് <ph name="TARGET_LANGUAGE" />-ലേക്ക് വിവർത്തനം ചെയ്യണോ?</translation>
<translation id="5019198164206649151">ബാക്കിംഗ് സംഭരണം മോശം അവസ്ഥയിലാണ്</translation>
<translation id="5031870354684148875">Google വിവര്‍ത്തനം എന്നതിനെക്കുറിച്ച് </translation>
+<translation id="5045550434625856497">പാസ്‌വേഡ് തെറ്റാണ്</translation>
+<translation id="5087286274860437796">സെർവറിന്റെ സർട്ടിഫിക്കറ്റിന് ഇപ്പോൾ സാധുതയില്ല.</translation>
<translation id="5089810972385038852">സ്റ്റേറ്റ്</translation>
+<translation id="5094747076828555589">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷ സർട്ടിഫിക്കറ്റിനെ Chromium-ത്തിന്ന് പരിചയമില്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
<translation id="5095208057601539847">പ്രവിശ്യ</translation>
<translation id="5145883236150621069">നയ പ്രതികരണത്തിൽ പിശക് കോഡ് ഉണ്ട്</translation>
<translation id="5172758083709347301">മെഷീൻ</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/> എന്നതില്‍‌ ഇല്ലേ? ഈ പിശക് റിപ്പോര്‍‌ട്ടുചെയ്യുക</translation>
+<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> എന്നതില്‍‌ ഇല്ലേ? ഈ പിശക് റിപ്പോര്‍‌ട്ടുചെയ്യുക</translation>
<translation id="5190835502935405962">ബുക്ക്‌മാര്‍‌ക്കുകള്‍‌ ബാര്‍‌</translation>
+<translation id="5199729219167945352">പരീക്ഷണങ്ങള്‍</translation>
+<translation id="5251803541071282808">ക്ലൗഡ്</translation>
<translation id="5295309862264981122">നാവിഗേഷന്‍ ഉറപ്പാക്കുക</translation>
<translation id="5299298092464848405">നയം പാഴ്‌സുചെയ്യുന്നതിൽ പിശക്</translation>
+<translation id="5316812925700871227">എതിർ ഘടികാരദിശയിൽ തിരിക്കുക</translation>
<translation id="5317780077021120954">സംരക്ഷിക്കുക</translation>
<translation id="536296301121032821">നയ ക്രമീകരണങ്ങൾ സംഭരിക്കുന്നതിൽ പരാജയപ്പെട്ടു</translation>
-<translation id="5439770059721715174">&quot;<ph name="ERROR_PATH"/>&quot; എന്നതിൽ സ്‌കീമ മൂല്ല്യനിർണ്ണയ പിശക്: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷ സർട്ടിഫിക്കറ്റിന് ഇപ്പോൾ സാധുതയുള്ളതല്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു ആക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
+<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" എന്നതിൽ സ്‌കീമ മൂല്ല്യനിർണ്ണയ പിശക്: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">മോശം നയ ടൈംസ്റ്റാമ്പ്</translation>
<translation id="5470861586879999274">&amp;എഡിറ്റുചെയ്യുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="5509780412636533143">നിയന്ത്രിത ബുക്കുമാർക്കുകൾ</translation>
<translation id="5523118979700054094">നയത്തിന്റെ പേര്</translation>
<translation id="552553974213252141">വാചകം ശരിയായി എക്‌സ്‌ട്രാക്റ്റുചെയ്‌തോ?</translation>
<translation id="5540224163453853">അഭ്യർത്ഥിച്ച ലേഖനം കണ്ടെത്താനായില്ല.</translation>
+<translation id="5556459405103347317">വീണ്ടും ലോഡുചെയ്യുക</translation>
<translation id="5565735124758917034">സജീവമാണ്</translation>
<translation id="560412284261940334">മാനേജുമെന്റ് പിന്തുണയ്‌ക്കുന്നില്ല</translation>
<translation id="5629630648637658800">നയ ക്രമീകരണങ്ങൾ ലോഡുചെയ്യുന്നതിൽ പരാജയപ്പെട്ടു</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">നിലവിലെ ഉപയോക്താവ്</translation>
<translation id="5813119285467412249">&amp;ചേർക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="5872918882028971132">പാരന്റ് നിർദ്ദേശങ്ങൾ</translation>
-<translation id="587701087903783706">മൊബൈൽ-സൗഹൃദ കാഴ്‌ച അടയ്‌ക്കുക</translation>
<translation id="59107663811261420">ഈ വ്യാപരിയ്‌ക്കായി ഈ തരത്തിലുള്ള കാർഡ് Google പേയ്‌മെന്റ് പിന്തുണയ്ക്കുന്നില്ല. മറ്റൊരു കാർഡ് തിരഞ്ഞെടുക്കുക.</translation>
+<translation id="5975083100439434680">സൂം ഔട്ട്</translation>
<translation id="5989320800837274978">ഒരു സ്ഥിരമായ പ്രോക്സി സെർവർ അല്ലെങ്കിൽ ഒരു .pac സ്‌ക്രിപ്റ്റ് URL വ്യക്തമാക്കിയിട്ടില്ല.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">അടയ്ക്കുക</translation>
+<translation id="6060685159320643512">ശ്രദ്ധിക്കൂ, ഈ പരീക്ഷണങ്ങള്‍ പാളിയേക്കാം‍ </translation>
+<translation id="6151417162996330722">സെർവർ സർട്ടിഫിക്കറ്റിന് ദൈർഘ്യമേറിയ ഒരു കാലയളവ് ഉണ്ട്.</translation>
<translation id="6154808779448689242">മടങ്ങിയ നയ ടോക്കൺ നിലവിലുള്ള ടോക്കണുമായി പൊരുത്തപ്പെടില്ല</translation>
<translation id="6165508094623778733">കൂടുതല്‍ മനസിലാക്കുക</translation>
<translation id="6259156558325130047">&amp;പുനഃക്രമീകരിക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> ബുക്ക്‌മാർക്കുകൾ</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> ബുക്ക്‌മാർക്കുകൾ</translation>
<translation id="6282194474023008486">തപാല്‍ കോഡ്</translation>
<translation id="6337534724793800597">പേരിന്റെ ക്രമത്തിൽ നയങ്ങൾ ഫിൽട്ടർ ചെയ്യുക</translation>
+<translation id="6387478394221739770">Chrome-ന്റെ രസകരമായ പുതിയ സവിശേഷതകളിൽ താൽപ്പര്യമുണ്ടോ? chrome.com/beta-യിൽ ഞങ്ങളുടെ ബീറ്റ ചാനൽ പരീക്ഷിക്കുക.</translation>
+<translation id="6426993025560594914">എല്ലാ പരീക്ഷണങ്ങളും നിങ്ങളുടെ പ്ലാറ്റ്‌ഫോമിൽ ലഭ്യമാണ്!</translation>
<translation id="6445051938772793705">രാജ്യം</translation>
<translation id="6458467102616083041">സ്ഥിരസ്ഥിതി തിരയൽ നയ പ്രകാരം ദൃശ്യമായതിനാൽ അവഗണിക്കപ്പെട്ടു.</translation>
<translation id="647261751007945333">ഉപകരണ നയങ്ങൾ</translation>
<translation id="6512448926095770873">ഈ പേജ് വിടുക</translation>
<translation id="6529602333819889595">&amp;ഇല്ലാതാക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="6550675742724504774">ഐച്ഛികങ്ങള്‍‌</translation>
-<translation id="6597614308054261376">നിങ്ങൾ <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> എന്നതിൽ എത്താൻ ശ്രമിക്കുന്നു. ഇപ്പോൾ ഈ പേജ് ഡാറ്റ സേവർ വഴി പ്രോക്‌സി ചെയ്യാനാകില്ല.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> തിരയല്‍</translation>
+<translation id="6597614308054261376">നിങ്ങൾ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> എന്നതിൽ എത്താൻ ശ്രമിക്കുന്നു. ഇപ്പോൾ ഈ പേജ് ഡാറ്റ സേവർ വഴി പ്രോക്‌സി ചെയ്യാനാകില്ല.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> തിരയല്‍</translation>
<translation id="6644283850729428850">ഈ നയം ഒഴിവാക്കി.</translation>
<translation id="6646897916597483132">നിങ്ങളുടെ കാർഡിന്റെ മുന്നിലുള്ള 4 അക്ക CVC നൽകുക</translation>
+<translation id="674375294223700098">അറിയപ്പെടാത്ത സെര്‍വര്‍ സര്‍ട്ടിഫിക്കറ്റ് പിശക്.</translation>
<translation id="6753269504797312559">നയ മൂല്യം</translation>
<translation id="6831043979455480757">വിവര്‍‌ത്തനം ചെയ്യുക</translation>
<translation id="6839929833149231406">ഏരിയ</translation>
<translation id="6874604403660855544">&amp;ചേർക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="6891596781022320156">നയ നില പിന്തുണയ്ക്കുന്നില്ല.</translation>
<translation id="6915804003454593391">ഉപയോക്താവ്:</translation>
+<translation id="6957887021205513506">സെർവറിന്റെ സർട്ടിഫിക്കറ്റ് വിശ്വസിക്കാൻ കൊള്ളാത്ത ഒന്നായി തോന്നുന്നു.</translation>
<translation id="6965382102122355670">ശരി</translation>
<translation id="6965978654500191972">ഉപാധി</translation>
<translation id="6970216967273061347">ജില്ല</translation>
<translation id="6973656660372572881">സ്ഥിരമായ പ്രോക്‌സി സെർവറുകളും ഒരു സ്‌ക്രിപ്റ്റ് URL-ഉം വ്യക്തമാക്കിയിരിക്കുന്നു.</translation>
<translation id="6980028882292583085">JavaScript അലേര്‍ട്ട്</translation>
<translation id="7012363358306927923">ചൈന UnionPay</translation>
+<translation id="7050187094878475250">നിങ്ങൾ <ph name="DOMAIN" /> എന്നതിലെത്താൻ ശ്രമിച്ചു, എന്നാൽ തീരെ വിശ്വാസയോഗ്യമല്ലാത്ത ഒരു കാലാവധിയുള്ള സർട്ടിഫിക്കറ്റാണ് സെർവർ കാണിക്കുന്നത്.</translation>
<translation id="7087282848513945231">രാജ്യം</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/> ഭാഷയിലേക്കുള്ള വിവർത്തനം പരാജയപ്പെട്ടു.</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" /> ഭാഷയിലേക്കുള്ള വിവർത്തനം പരാജയപ്പെട്ടു.</translation>
<translation id="7139724024395191329">എമിറേറ്റ്</translation>
+<translation id="7179921470347911571">ഇപ്പോള്‍ വീണ്ടും സമാരംഭിക്കുക</translation>
<translation id="7180611975245234373">പുതുക്കുക</translation>
<translation id="7182878459783632708">നയങ്ങളൊന്നും സജ്ജമാക്കിയിട്ടില്ല</translation>
-<translation id="7186367841673660872">ഈ പേജ്<ph name="ORIGINAL_LANGUAGE"/>ല്‍‌ നിന്നും<ph name="LANGUAGE_LANGUAGE"/>ലേക്ക് വിവര്‍‌ത്തനം ചെയ്‌തു</translation>
+<translation id="7186367841673660872">ഈ പേജ്<ph name="ORIGINAL_LANGUAGE" />ല്‍‌ നിന്നും<ph name="LANGUAGE_LANGUAGE" />ലേക്ക് വിവര്‍‌ത്തനം ചെയ്‌തു</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531"><ph name="SEARCH_TERMS"/> നായി <ph name="SITE_NAME"/> തിരയുക</translation>
+<translation id="7208899522964477531"><ph name="SEARCH_TERMS" /> നായി <ph name="SITE_NAME" /> തിരയുക</translation>
+<translation id="725866823122871198">നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ തീയതിയും സമയവും (<ph name="DATE_AND_TIME" />) തെറ്റായതിനാൽ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> എന്നതിലേക്കുള്ള സ്വകാര്യ കണക്ഷൻ സ്ഥാപിക്കാനാവില്ല.</translation>
<translation id="7275334191706090484">നിയന്ത്രിത ബുക്ക്‌മാർക്കുകൾ</translation>
<translation id="7298195798382681320">ശുപാർശചെയ്യുന്നത്</translation>
<translation id="7334320624316649418">&amp;പുനഃക്രമീകരിക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">നിർബന്ധിതം</translation>
<translation id="7542995811387359312">ഈ ഫോം ഒരു സുരക്ഷിത കണക്ഷന്‍ ഉപയോഗിക്കാത്തതിനാല്‍ സ്വപ്രേരിത ക്രെഡിറ്റ് കാര്‍ഡ് പൂരിപ്പിക്കല്‍ അപ്രാപ്തമാക്കി.</translation>
-<translation id="7568593326407688803">ഈ പേജ്<ph name="ORIGINAL_LANGUAGE"/>ലാണ് നിങ്ങളത് വിവര്‍‌ത്തനം ചെയ്യാന്‍‌ താല്‍‌പ്പര്യപ്പെടുന്നോ?</translation>
+<translation id="7567204685887185387">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; സെർവറിന്റെ സുരക്ഷ സർട്ടിഫിക്കറ്റ് വഞ്ചനാപരമായി ഇഷ്യൂ ചെയ്‌തിരിക്കാം. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
+<translation id="7568593326407688803">ഈ പേജ്<ph name="ORIGINAL_LANGUAGE" />ലാണ് നിങ്ങളത് വിവര്‍‌ത്തനം ചെയ്യാന്‍‌ താല്‍‌പ്പര്യപ്പെടുന്നോ?</translation>
<translation id="7569952961197462199">Chrome-ൽ നിന്ന് ക്രെഡിറ്റ് കാർഡ് നീക്കംചെയ്യണോ?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/> ഒരിക്കലും വിവര്‍‌ത്തനം ചെയ്യരുത്</translation>
-<translation id="7610193165460212391">മൂല്യം പരിധിക്ക് പുറത്താണ് <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">സെർവറിന്റെ സർട്ടിഫിക്കറ്റ് പേരിന്റെ പരിധി ലംഘിക്കുന്നു.</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" /> ഒരിക്കലും വിവര്‍‌ത്തനം ചെയ്യരുത്</translation>
+<translation id="7610193165460212391">മൂല്യം പരിധിക്ക് പുറത്താണ് <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">പുതിയ Chrome-ന്റെ രസകരമായ സവിശേഷതകളിൽ താൽപ്പര്യമുണ്ടോ? chrome.com/dev-ൽ ഞങ്ങളുടെ ഡവലപ്പർ ചാനൽ പരീക്ഷിച്ചുനോക്കുക.</translation>
<translation id="7752995774971033316">നിയന്ത്രിക്കാനാകാത്തത്</translation>
+<translation id="7761701407923456692">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് URL മായി പൊരുത്തപ്പെടുന്നില്ല.</translation>
<translation id="777702478322588152">പ്രിഫെക്‌ചർ</translation>
<translation id="7791543448312431591">ചേര്‍ക്കൂ</translation>
<translation id="7805768142964895445">നില</translation>
<translation id="7813600968533626083">Chrome-ൽ നിന്നുള്ള നിർദ്ദേശം നീക്കംചെയ്യണോ?</translation>
<translation id="7887683347370398519">നിങ്ങളുടെ CVC പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക</translation>
<translation id="7935318582918952113">DOM ഡിസ്‌റ്റിലർ</translation>
+<translation id="7938958445268990899">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് ഇതുവരെയും സാധുവല്ല.</translation>
<translation id="7956713633345437162">മൊബൈൽ ബുക്ക്‌മാർക്കുകൾ</translation>
<translation id="7961015016161918242">ഒരിക്കലും</translation>
<translation id="7977590112176369853">&lt;ചോദ്യം നല്‍കുക&gt;</translation>
-<translation id="7983301409776629893">എല്ലായ്‌പ്പോഴും <ph name="ORIGINAL_LANGUAGE"/> നെ <ph name="TARGET_LANGUAGE"/> ലേക്ക് വിവര്‍‌ത്തനം ചെയ്യുക</translation>
+<translation id="7983301409776629893">എല്ലായ്‌പ്പോഴും <ph name="ORIGINAL_LANGUAGE" /> നെ <ph name="TARGET_LANGUAGE" /> ലേക്ക് വിവര്‍‌ത്തനം ചെയ്യുക</translation>
<translation id="7988324688042446538">ഡെസ്‌ക്‌ടോപ്പ് ബുക്ക്‌മാർക്കുകൾ</translation>
<translation id="7995512525968007366">വ്യക്തമാക്കിയിട്ടില്ല</translation>
-<translation id="8034522405403831421">ഈ പേജ് <ph name="SOURCE_LANGUAGE"/>-ലാണ്. <ph name="TARGET_LANGUAGE"/>-ലേക്ക് വിവർത്തനം ചെയ്യണോ?</translation>
+<translation id="8003882219468422867">എന്റർപ്രൈസ് അസാധുവാക്കൽ</translation>
+<translation id="8034522405403831421">ഈ പേജ് <ph name="SOURCE_LANGUAGE" />-ലാണ്. <ph name="TARGET_LANGUAGE" />-ലേക്ക് വിവർത്തനം ചെയ്യണോ?</translation>
<translation id="8088680233425245692">ലേഖനം കാണുന്നത് പരാജയപ്പെട്ടു.</translation>
<translation id="8091372947890762290">സെർവറിൽ സജീവമാക്കൽ തീർപ്പാക്കിയിട്ടില്ല</translation>
<translation id="8194797478851900357">&amp;നീക്കുന്നത് പഴയപടിയാക്കുക</translation>
-<translation id="8201077131113104583">&quot;<ph name="EXTENSION_ID"/>&quot; എന്ന ഐഡിയുള്ള വിപുലീകരണത്തിന്റെ അപ്‌ഡേറ്റ് URL അസാധുവാണ്.</translation>
+<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" എന്ന ഐഡിയുള്ള വിപുലീകരണത്തിന്റെ അപ്‌ഡേറ്റ് URL അസാധുവാണ്.</translation>
<translation id="8208216423136871611">സംരക്ഷിക്കരുത്</translation>
<translation id="8218327578424803826">നൽകിയിരിക്കുന്ന ലൊക്കേഷൻ:</translation>
<translation id="8249320324621329438">അവസാനം ലഭ്യമായത്:</translation>
+<translation id="8294431847097064396">ഉറവിടം</translation>
<translation id="8308427013383895095">നെറ്റ്വര്‍ക്ക് കണക്ഷനിലെ ഒരു പിശക് കാരണം വിവര്‍ത്തനം പരാജയപ്പെട്ടു.</translation>
<translation id="8311778656528046050">ഈ പേജ് വീണ്ടും ലോഡുചെയ്യാൻ നിങ്ങൾ ആഗ്രഹിക്കുന്നുവെന്ന് തീർച്ചയാണോ?</translation>
<translation id="8349305172487531364">ബുക്മാര്‍ക്ക് ബാര്‍</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">ഇതിന് ബാധകമാക്കുന്നു</translation>
<translation id="8530504477309582336">Google പേയ്‌മെന്റ് ഇത്തരം കാർഡിനെ പിന്തുണയ്ക്കുന്നില്ല. മറ്റൊന്ന് തിരഞ്ഞെടുക്കുക.</translation>
<translation id="8553075262323480129">പേജിന്‍റെ ഭാഷ നിര്‍‌ണ്ണയിക്കാന്‍‌ കഴിയാത്തതിനാല്‍‌ വിവര്‍‌ത്തനം പരാജയപ്പെട്ടു.</translation>
-<translation id="8571890674111243710"><ph name="LANGUAGE"/> ലേക്ക് പേജ് വിവര്‍‌ത്തനം ചെയ്യുന്നു...</translation>
+<translation id="8559762987265718583">നിങ്ങളുടെ ഉപകരണത്തിന്റെ തീയതിയും സമയവും (<ph name="DATE_AND_TIME" />) തെറ്റായതിനാൽ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> എന്നതിലേക്കുള്ള സ്വകാര്യ കണക്ഷൻ സ്ഥാപിക്കാനാവില്ല.</translation>
+<translation id="8571890674111243710"><ph name="LANGUAGE" /> ലേക്ക് പേജ് വിവര്‍‌ത്തനം ചെയ്യുന്നു...</translation>
+<translation id="8647750283161643317">എല്ലാം സ്ഥിരമായി പുനഃസജ്ജമാക്കുക</translation>
<translation id="8713130696108419660">ഇനിഷ്യൽ സിഗ്നേച്ചർ മോശമാണ്</translation>
<translation id="8725066075913043281">വീണ്ടും ശ്രമിക്കുക</translation>
+<translation id="8738058698779197622">ഒരു സുരക്ഷിത കണക്ഷൻ സ്ഥാപിക്കുന്നതിന്, നിങ്ങളുടെ ക്ലോക്ക് ശരിയായി സജ്ജീകരിക്കേണ്ടതുണ്ട്. വെബ്‌സൈറ്റുകൾ സ്വയം തിരിച്ചറിയുന്നതിന് ഉപയോഗിക്കുന്ന സർട്ടിഫിക്കറ്റുകൾ, നിർദ്ദിഷ്‌ട സമയ പരിധിയ്‌ക്ക് മാത്രമായി സാധുതയുള്ളതിനാലാണിത്. നിങ്ങളുടെ ഉപകരണത്തിന്റെ ക്ലോക്ക് തെറ്റായിരിക്കുന്നതിനാൽ, Chromium-ന് ഈ സർട്ടിഫിക്കറ്റുകൾ പരിശോധിച്ചുറപ്പിക്കാനാവില്ല.</translation>
<translation id="8790007591277257123">&amp;ഇല്ലാതാക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="8804164990146287819">സ്വകാര്യത നയം</translation>
+<translation id="8820817407110198400">ബുക്ക്‌മാര്‍ക്കുകള്‍</translation>
<translation id="8824019021993735287">Chrome-ന് ഇപ്പോൾ നിങ്ങളുടെ കാർഡ് പരിശോധിപ്പിച്ചുറപ്പിക്കാൻ കഴിഞ്ഞില്ല. പിന്നീട് വീണ്ടും ശ്രമിക്കുക.</translation>
<translation id="8834246243508017242">കോൺടാക്‌റ്റുകൾ ഉപയോഗിച്ച് ഓട്ടോഫിൽ പ്രവർത്തനക്ഷമമാക്കുക…</translation>
<translation id="883848425547221593">മറ്റുള്ള ബുക്ക്‌മാര്‍‌ക്കുകള്‍‌</translation>
+<translation id="884923133447025588">അസാധുവാക്കല്‍ പ്രവര്‍ത്തനം കണ്ടെത്തിയിട്ടില്ല.</translation>
<translation id="8866481888320382733">നയ ക്രമീകരണങ്ങൾ പാഴ്‌സുചെയ്യുന്നതിൽ പിശക്</translation>
<translation id="8876793034577346603">നെറ്റ്‌വർക്ക് കോൺഫിഗറേഷൻ പാഴ്‌സുചെയ്യുന്നതിൽ പരാജയപ്പെട്ടു</translation>
<translation id="8891727572606052622">അസാധുവായ പ്രോക്സി മോഡ്</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/> കമാന്‍റ്:<ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">ക്ഷമിക്കണം, ഈ പരീക്ഷണം നിങ്ങളുടെ പ്ലാറ്റ്ഫോമിൽ ലഭ്യമല്ല.</translation>
+<translation id="8903921497873541725">സൂം ഇന്‍</translation>
+<translation id="8932102934695377596">നിങ്ങളുടെ ക്ലോക്ക് വളരെ പിന്നിലാണ്</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" /> കമാന്‍റ്:<ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് കാലഹരണപ്പെട്ടു.</translation>
<translation id="8988760548304185580">നിങ്ങളുടെ കാർഡിന്റെ പുറകിലുള്ള കാലഹരണപ്പെടൽ തീയതിയും 3-അക്ക CVC-യും നൽകുക</translation>
-<translation id="9020542370529661692">ഈ പേജ് <ph name="TARGET_LANGUAGE"/>-ലേക്ക് വിവർത്തനം ചെയ്‌തു</translation>
+<translation id="901974403500617787">ഉടമയ്‌ക്ക് മാത്രമേ സിസ്റ്റത്തിലാകമാനം ബാധകമാക്കാവുന്ന ഫ്ലാഗ് സജ്ജമാക്കാനാകൂ: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">ഈ പേജ് <ph name="TARGET_LANGUAGE" />-ലേക്ക് വിവർത്തനം ചെയ്‌തു</translation>
+<translation id="9049981332609050619">നിങ്ങള്‍ <ph name="DOMAIN" /> എന്നതില്‍ എത്താന്‍ ശ്രമിച്ചു, പക്ഷേ സെര്‍വര്‍ ഒരു അസാധുവായ സര്‍ട്ടിഫിക്കറ്റ് അവതരിപ്പിച്ചു.</translation>
<translation id="9125941078353557812">നിങ്ങളുടെ കാർഡിന്റെ പുറകിലുള്ള 3 അക്ക CVC നൽകുക</translation>
<translation id="9137013805542155359">യഥാര്‍ത്ഥമായത് കാണിക്കുക</translation>
<translation id="9148507642005240123">&amp;എഡിറ്റുചെയ്യുന്നത് പഴയപടിയാക്കുക</translation>
<translation id="9154176715500758432">ഈ പേജില്‍ നില്‍ക്കുക</translation>
<translation id="9170848237812810038">‍&amp;പൂര്‍വാവസ്ഥയിലാക്കുക</translation>
+<translation id="917450738466192189">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് അസാധുവാണ്.</translation>
+<translation id="9187827965378254003">ഓ, ഇത് ഇപ്പോള്‍ പരീക്ഷണങ്ങളൊന്നും ലഭ്യമല്ലാത്തതുപോലെ കാണപ്പെടുന്നു.</translation>
<translation id="9207861905230894330">ലേഖനം ചേർക്കുന്നത് പരാജയപ്പെട്ടു.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ഫോം മായ്‌ക്കുക</translation>
+<translation id="988159990683914416">വികാസക പതിപ്പ്</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_mr.xtb b/chromium/components/strings/components_strings_mr.xtb
index 14a4243392f..c98f5812a70 100644
--- a/chromium/components/strings/components_strings_mr.xtb
+++ b/chromium/components/strings/components_strings_mr.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="mr">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="mr">
+<translation id="1032854598605920125">घड्याळाच्या दिशेने फिरवा</translation>
<translation id="1055184225775184556">&amp;जोडा पूर्ववत करा</translation>
<translation id="106701514854093668">डेस्‍कटॉप बुकमार्क</translation>
-<translation id="1103523840287552314">नेहमी अनुवाद करा <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">रूंदीत फिट करा</translation>
+<translation id="1103523840287552314">नेहमी अनुवाद करा <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;पुनर्क्रमित करा पूर्ववत करा</translation>
<translation id="111844081046043029">आपली खात्री आहे की आपण हे पृष्ठ सोडू इच्छिता?</translation>
<translation id="112840717907525620">धोरण कॅशे ठीक</translation>
<translation id="1132774398110320017">Chrome स्वयंभरण सेटिंग्ज...</translation>
-<translation id="1152921474424827756"><ph name="URL"/> च्या <ph name="BEGIN_LINK"/>कॅशे केलेल्या कॉपीवर<ph name="END_LINK"/> प्रवेश करा</translation>
+<translation id="1150979032973867961">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता प्रमाणपत्र आपल्या संगणकाच्या ऑपरेटिंग प्रणालीद्वारे विश्वसनीय नाही. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.</translation>
+<translation id="1152921474424827756"><ph name="URL" /> च्या <ph name="BEGIN_LINK" />कॅशे केलेल्या कॉपीवर<ph name="END_LINK" /> प्रवेश करा</translation>
+<translation id="121201262018556460">आपण <ph name="DOMAIN" /> वर पोहोचण्याचा प्रयत्न केलात, परंतु सर्व्हरने एक कमकुवत की असलेले प्रमाणपत्र सादर केले. आक्रमणकर्त्याने गोपनीय की तोडलेली असू शकते आणि सर्व्हर हे आपल्याला अपेक्षित असणारे सर्व्हर नसू शकते (आपण कदाचित आक्रमणकर्त्याशी संप्रेषण करत असाल).</translation>
<translation id="1227224963052638717">अज्ञात धोरण.</translation>
<translation id="1227633850867390598">मूल्य लपवा</translation>
<translation id="1228893227497259893">चुकीचा अस्तित्व ओळखकर्ता</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">नावनोंदणी डोमेन:</translation>
<translation id="1344588688991793829">Chromium स्वयंभरण सेटिंग्ज...</translation>
<translation id="1426410128494586442">होय</translation>
+<translation id="1430915738399379752">मुद्रण</translation>
<translation id="1455235771979731432">आपले कार्ड सत्यापित करताना समस्या आली. आपले इंटरनेट कनेक्शन तपासा आणि पुन्हा प्रयत्न करा.</translation>
<translation id="1491151370853475546">हे पृष्ठ रीलोड करा</translation>
<translation id="1549470594296187301">हे वैशिष्‍ट्य वापरण्‍यासाठी JavaScript सक्षम करणे आवश्‍यक आहे.</translation>
-<translation id="1639239467298939599">लोड करीत आहे</translation>
<translation id="1640180200866533862">वापरकर्ता धोरणे</translation>
<translation id="1644184664548287040">नेटवर्क कॉन्फिगरेशन अवैध आहे आणि आयात केले जाऊ शकले नाही.</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> वरील पृष्ठ म्हणते:</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="168841957122794586">सर्व्हर प्रमाणपत्रात एक कमकुवत क्रिप्टोग्राफिक की आहे.</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> वरील पृष्ठ म्हणते:</translation>
+<translation id="1706954506755087368">{1,plural, =1{हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षा प्रमाणपत्र उद्यापासून मानले जाईल. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.}one{हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षा प्रमाणपत्र पुढील # दिवसांपासून मानले जाईल. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.}other{हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षा प्रमाणपत्र पुढील # दिवसांपासून मानले जाईल. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता प्रमाणपत्र आपल्या डिव्हाइसच्या ऑपरेटिंग प्रणालीद्वारे विश्वसनीय नाही. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.</translation>
<translation id="1821930232296380041">अवैध विनंती किंवा विनंती मापदंड</translation>
-<translation id="1853748787962613237">लेख प्रदर्शित करण्यात अयशस्वी.</translation>
<translation id="1871208020102129563">प्रॉक्सी निश्चित प्रॉक्सी सर्व्हर वापरण्‍यास सेट करण्‍यात आले आहे, .pac स्क्रिप्ट URL नव्हे.</translation>
-<translation id="1875753206475436906">अन्वेषणात्मक प्रकार: <ph name="HEURISTIC_TYPE"/>
- सर्व्हर प्रकार: <ph name="SERVER_TYPE"/>
- फील्ड स्वाक्षरी: <ph name="FIELD_SIGNATURE"/>
- फॉर्म स्वाक्षरी: <ph name="FORM_SIGNATURE"/>
- प्रायोगिक id: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158"><ph name="LINK"/> दुव्याकडे जा</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> बुकमार्क</translation>
+<translation id="194030505837763158"><ph name="LINK" /> दुव्याकडे जा</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> बुकमार्क</translation>
<translation id="1973335181906896915">क्रमीकरण त्रुटी</translation>
+<translation id="1974060860693918893">प्रगत</translation>
<translation id="2025186561304664664">प्रॉक्सी स्वयंचलित ‍कॉन्फिगरेशनवर सेट करण्‍यात आली.</translation>
<translation id="2025623846716345241">रीलोड करण्याची पुष्टी करा</translation>
-<translation id="2030481566774242610">आपल्याला असे म्हणायचे होते <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">आपल्याला असे म्हणायचे होते <ph name="LINK" />?</translation>
<translation id="2053553514270667976">पिनकोड</translation>
<translation id="20817612488360358">सिस्टम प्रॉक्सी सेटिंग्ज वापरण्‍यास सेट करण्‍यात आल्या परंतु एक सुस्पष्‍ट प्रॉक्सी कॉन्फिगरेशन देखील निर्दिष्‍ट करण्‍यात आले.</translation>
<translation id="2094505752054353250">डोमेन जुळत नाही</translation>
<translation id="2096368010154057602">विभाग</translation>
<translation id="2113977810652731515">कार्ड</translation>
-<translation id="2114841414352855701">दुर्लक्ष केले कारण ते <ph name="POLICY_NAME"/> कडून अधिलिखित झाले होते.</translation>
+<translation id="2114841414352855701">दुर्लक्ष केले कारण ते <ph name="POLICY_NAME" /> कडून अधिलिखित झाले होते.</translation>
+<translation id="2128531968068887769">मूळ क्लायंट</translation>
<translation id="213826338245044447">Mobile बुकमार्क</translation>
+<translation id="2171101176734966184">आपण <ph name="DOMAIN" /> वर पोहोचण्याचा प्रयत्न केला परंतु सर्व्हरने एखाद्या कमकूवत स्वाक्षरी अल्गोरिदमचा वापर करून स्वाक्षरीकृत केलेले प्रमाणपत्र सादर केले. याचा अर्थ असा आहे की सर्व्हरने सादर केलेली सुरक्षितता क्रेडेन्शियल बनावट असू शकतात आणि आपण अपेक्षा करीत असलेला सर्व्हर हा नसावा (आपण कदाचित एखाद्या आक्रमणकर्त्यासह संप्रेषण करीत आहात).</translation>
<translation id="2181821976797666341">धोरणे</translation>
<translation id="2212735316055980242">धोरण आढळले नाही</translation>
<translation id="2213606439339815911">प्रविष्ट्या आणत आहे...</translation>
<translation id="225207911366869382">हे मूल्य या धोरणासाठी नापसंत करण्‍यात आले आहे.</translation>
<translation id="2262243747453050782">HTTP त्रुटी</translation>
-<translation id="2270192940992995399">लेख शोधण्यात अयशस्वी.</translation>
-<translation id="2328300916057834155"><ph name="ENTRY_INDEX"/> अनुक्रमणिकेमधील अवैध बुकमार्ककडे दुर्लक्ष केले</translation>
+<translation id="2282872951544483773">अनुपलब्ध प्रयोग</translation>
+<translation id="229702904922032456">अंतस्थ प्रमाणपत्राचा रूट कालबाह्य झाला आहे.</translation>
+<translation id="2328300916057834155"><ph name="ENTRY_INDEX" /> अनुक्रमणिकेमधील अवैध बुकमार्ककडे दुर्लक्ष केले</translation>
<translation id="2354001756790975382">इतर बुकमार्क</translation>
<translation id="2359808026110333948">सुरू ठेवा</translation>
<translation id="2367567093518048410">दर्जा</translation>
+<translation id="2384307209577226199">एंटरप्राइझ डीफॉल्ट</translation>
+<translation id="2386255080630008482">सर्व्हरचे प्रमाणपत्र निरस्त केले गेले.</translation>
<translation id="2392959068659972793">कोणतेही मूल्य सेट केल्याशिवाय धोरणे दर्शवा</translation>
<translation id="2396249848217231973">&amp;हटवा पूर्ववत करा</translation>
+<translation id="2413528052993050574">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता प्रमाणपत्र कदाचित रद्द केले असू शकते. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.</translation>
<translation id="2455981314101692989">या वेबपृष्ठाने या फॉर्मकरिता स्वयंचलितरित्या भरणे अक्षम केले आहे.</translation>
<translation id="2479410451996844060">अवैध शोध URL.</translation>
+<translation id="2491120439723279231">सर्व्हरच्या प्रमाणपत्रात त्रुटी आहेत.</translation>
<translation id="2495083838625180221">JSON विश्लेषक</translation>
<translation id="2498091847651709837">नवीन कार्ड स्कॅन करा</translation>
<translation id="2556876185419854533">&amp; संपादित करा पूर्ववत करा</translation>
-<translation id="2581221116934462656">आपण पुढील वेळी या साइटवरून <ph name="PRODUCT_NAME"/> ने <ph name="LANGUAGE_NAME"/> पृष्‍ठे भाषांतरित करण्‍याची ऑफर द्यावी असे इच्छिता?</translation>
+<translation id="2581221116934462656">आपण पुढील वेळी या साइटवरून <ph name="PRODUCT_NAME" /> ने <ph name="LANGUAGE_NAME" /> पृष्‍ठे भाषांतरित करण्‍याची ऑफर द्यावी असे इच्छिता?</translation>
<translation id="2587841377698384444">शब्दकोश API ID:</translation>
<translation id="2597378329261239068">हा दस्तऐवज संकेतशब्द संरक्षित आहे. कृपया संकेतशब्द प्रविष्ट करा.</translation>
+<translation id="2625385379895617796">आपले घड्याळ पुढे आहे</translation>
<translation id="2639739919103226564">स्थिती:</translation>
+<translation id="2653659639078652383">सबमिट करा</translation>
<translation id="2704283930420550640">मूल्य स्वरुपनाशी जुळत नाही.</translation>
<translation id="2721148159707890343">विनंती यशस्वी</translation>
+<translation id="2728127805433021124">सर्व्हरचे प्रमाणपत्र कमकुवत स्वाक्षरी अल्गोरिदम वापरून स्वाक्षरित केले आहे.</translation>
<translation id="2774256287122201187">आपण सुरु ठेवू शकता. आपण पृष्ठावर सुरु ठेवल्यास, ही चेतावणी पाच मिनिटे पुन्हा दिसणार नाही.</translation>
<translation id="277499241957683684">डिव्हाइस रेकॉर्ड गहाळ</translation>
<translation id="2835170189407361413">फॉर्म क्लिअर करा</translation>
-<translation id="2855922900409897335">आपले <ph name="CREDIT_CARD"/> सत्यापित करा</translation>
+<translation id="2855922900409897335">आपले <ph name="CREDIT_CARD" /> सत्यापित करा</translation>
+<translation id="2915500479781995473">हे सर्व्हर ते <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकले नाही; त्याचे सुरक्षितता प्रमाणपत्र कालबाह्य झाले आहे. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते. आपल्या संगणकाचे घड्याळ सध्या <ph name="CURRENT_TIME" /> वर सेट केले आहे. ते बरोबर वाटते आहे? नसल्यास, आपण आपल्या प्रणालीचे घड्याळ दुरुस्त करावे आणि नंतर हे पृष्ठ रीफ्रेश करावे.</translation>
+<translation id="2922350208395188000">सर्व्हरचे प्रमाणपत्र तपासणे शक्य नाही.</translation>
+<translation id="2941952326391522266">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता प्रमाणपत्र <ph name="DOMAIN2" /> वरील आहे. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.</translation>
<translation id="2958431318199492670">नेटवर्क कॉन्फिगरेशन ONC मानकाचे पालन करत नाही. कॉन्फिगरेशनचे भाग आयात केले जाऊ शकत नाहीत.</translation>
<translation id="2972581237482394796">&amp;पुन्हा करा</translation>
-<translation id="3010559122411665027">सूची प्रविष्टी &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">सूची प्रविष्टी "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">चुकीचा धोरण प्रकार</translation>
<translation id="3105172416063519923">मालमत्ता ID:</translation>
<translation id="3145945101586104090">प्रतिसाद डीकोड करण्यात अयशस्वी</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">बेट</translation>
<translation id="3219579145727097045">आपल्या कार्डच्या समोरच्या भागावरील कालबाह्यता तारीख आणि 4-अंकी CVC प्रविष्ट करा</translation>
-<translation id="3228969707346345236">व्यवहार अयशस्वी झाला कारण पृष्ठ पूर्वीपासून <ph name="LANGUAGE"/> मध्ये आहे.</translation>
+<translation id="3225919329040284222">सर्व्हरने असे प्रमाणपत्र सादर केले आहे जे अंगभूत अपेक्षांशी जुळत नाही. या अपेक्षा आपल्याला संरक्षित करण्यासाठी विशिष्ट, उच्च-सुरक्षिततेच्या वेबसाइटसाठी समाविष्ट केल्या आहेत.</translation>
+<translation id="3228969707346345236">व्यवहार अयशस्वी झाला कारण पृष्ठ पूर्वीपासून <ph name="LANGUAGE" /> मध्ये आहे.</translation>
<translation id="3270847123878663523">&amp;पुनर्क्रमित करा पूर्ववत करा</translation>
+<translation id="3286538390144397061">त्वरित रीस्टार्ट करा</translation>
<translation id="333371639341676808">अतिरिक्त संवाद तयार करण्यापासून या पृष्ठाला प्रतिबंधित करा.</translation>
-<translation id="3369366829301677151">आपले <ph name="CREDIT_CARD"/> अद्यतनित आणि सत्यापित करा</translation>
+<translation id="3340978935015468852">सेटिंग्ज</translation>
+<translation id="3369192424181595722">घड्याळ त्रुटी</translation>
+<translation id="3369366829301677151">आपले <ph name="CREDIT_CARD" /> अद्यतनित आणि सत्यापित करा</translation>
<translation id="337363190475750230">तरतूद रद्द केली</translation>
<translation id="3377188786107721145">धोरण विश्लेषण त्रुटी</translation>
<translation id="3380365263193509176">अज्ञात त्रुटी</translation>
<translation id="3380864720620200369">क्लायंट ID:</translation>
<translation id="3427342743765426898">&amp;संपादित करा पुन्हा करा</translation>
+<translation id="3435896845095436175">सक्षम करा</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">मध्यंतर प्राप्त करा:</translation>
+<translation id="3462200631372590220">प्रगत लपवा</translation>
+<translation id="3528171143076753409">सर्व्हरचे प्रमाणपत्र विश्वासनीय नाही.</translation>
<translation id="3542684924769048008">यासाठी संकेतशब्द वापरा:</translation>
<translation id="3583757800736429874">&amp;हलवा पुन्हा करा</translation>
<translation id="3623476034248543066">मूल्य दर्शवा</translation>
+<translation id="3648607100222897006">ही प्रायोगिक वैशिष्ट्ये कधीही बदलू, खंडित होऊ किंवा अदृश्य होऊ शकतात. आपण या प्रयोगांपैकी एकही चालू ठेवल्यास काय होऊ शकते याबद्दल आम्ही निश्चितपणे कोणतीही हमी व्यक्त करत नाही आणि आपला ब्राउझर कदाचित आपोआप पेटू शकतो. चेष्टा सोडून द्या, आपला ब्राउझर आपला सर्व डेटा हटवू शकतो, किंवा आपली सुरक्षा आणि गोपनीयतेशी अनपेक्षित मार्गांनी तडजोड केली जाऊ शकते. आपण सक्षम केलेले कोणतेही प्रयोग या ब्राउझरच्या सर्व वापरकर्त्यांसाठी सक्षम केले जातील. कृपया सावधगिरीने पुढे जा.</translation>
<translation id="3650584904733503804">प्रमाणीकरण यशस्वी</translation>
<translation id="370665806235115550">लोड करीत आहे...</translation>
<translation id="3712624925041724820">परवाने संपुष्टात</translation>
<translation id="3739623965217189342">आपण कॉपी केलेल्याचा दुवा जोडा</translation>
<translation id="375403751935624634">सर्व्हर त्रुटीमुळे अनुवाद अयशस्वी झाला.</translation>
<translation id="385051799172605136">मागील</translation>
+<translation id="3858027520442213535">तारीख आणि वेळ अद्यतनित करा</translation>
<translation id="3884278016824448484">संघर्ष करणारा डिव्हाइस अभिज्ञापक</translation>
<translation id="3885155851504623709">पॅरिश</translation>
<translation id="3934680773876859118">PDF दस्तऐवज लोड करणे अयशस्वी</translation>
<translation id="3963721102035795474">वाचक मोड</translation>
<translation id="4030383055268325496">&amp;जोडा पूर्ववत करा</translation>
-<translation id="4058922952496707368">की &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">चेतावणी:</translation>
+<translation id="4058922952496707368">की "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">प्रॉक्सी कॉन्फिगरेशन .pac स्क्रिप्ट URL वापरण्‍यास सेट करण्‍यात आले आहे, निश्चित प्रॉक्सी सर्व्हर नव्हे.</translation>
<translation id="409504436206021213">रीलोड करु नका</translation>
<translation id="4103249731201008433">डिव्हाइस सिरीयल क्रमांक अवैध आहे</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">खराब स्वाक्षरी</translation>
<translation id="4269787794583293679">(वापरकर्तानाव नाही)</translation>
<translation id="4300246636397505754">पालक सूचना</translation>
-<translation id="4372948949327679948">अपेक्षित <ph name="VALUE_TYPE"/> मूल्य.</translation>
+<translation id="4325863107915753736">लेख शोधण्यात अयशस्वी</translation>
+<translation id="4372948949327679948">अपेक्षित <ph name="VALUE_TYPE" /> मूल्य.</translation>
+<translation id="4377125064752653719">आपण <ph name="DOMAIN" /> वर पोहोचण्याचा प्रयत्न केला, परंतु सर्व्हरने सादर केलेले प्रमाणपत्र त्याच्या जारीकर्त्याद्वारे मागे घेतले गेले आहे. याचा अर्थ सर्व्हरने सादर केलेल्या सुरक्षा क्रेडेन्शियलवर अजिबात ठेवला जाऊ नये. आपण कदाचित आक्रमणकर्त्याशी संप्रेषण करत आहात.</translation>
+<translation id="4394049700291259645">अक्षम करा</translation>
+<translation id="4424024547088906515">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता प्रमाणपत्र Chrome द्वारे विश्वसनीय नाही. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.</translation>
<translation id="443673843213245140">प्रॉक्सीचा वापर अक्षम करण्‍यात आला आहे पण एक सुस्पष्‍ट प्रॉक्सी कॉन्‍फिगरेशन निर्दिष्‍ट करण्‍यात आले आहे.</translation>
-<translation id="4506176782989081258">प्रमाणीकरण त्रुटी: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">प्रमाणीकरण त्रुटी: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chrome मधून पत्ता काढायचा?</translation>
<translation id="4594403342090139922">&amp;हटवा पूर्ववत करा</translation>
<translation id="4607653538520819196">डेटा बचतकर्त्याद्वारे हे पृष्ठ प्रॉक्सी केले जाऊ शकत नाही.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याच्या सुरक्षितता प्रमाणपत्रात त्रुटी आहेत. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.</translation>
<translation id="4726672564094551039">धोरणे रीलोड करा</translation>
+<translation id="4728558894243024398">प्लॅटफॉर्म</translation>
+<translation id="4771973620359291008">एक अज्ञात त्रुटी आली आहे.</translation>
<translation id="4800132727771399293">आपली कालबाह्यता तारीख आणि CVC तपासा आणि पुन्हा प्रयत्न करा</translation>
<translation id="4813512666221746211">नेटवर्क त्रुटी</translation>
+<translation id="4816492930507672669">पृष्‍ठानुरुप करा</translation>
<translation id="4850886885716139402">पहा</translation>
-<translation id="4923417429809017348">हे पृष्ठ अज्ञात भाषेतून <ph name="LANGUAGE_LANGUAGE"/> मध्ये अनुवादित करण्यात आले</translation>
+<translation id="4923417429809017348">हे पृष्ठ अज्ञात भाषेतून <ph name="LANGUAGE_LANGUAGE" /> मध्ये अनुवादित करण्यात आले</translation>
<translation id="4926049483395192435">निर्दिष्‍ट केले जाणे आवश्‍यक आहे.</translation>
<translation id="4968547170521245791">प्रॉक्सी करू शकत नाही</translation>
-<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE"/> मधून <ph name="TARGET_LANGUAGE"/> मध्ये भाषांतरित करायचे?</translation>
+<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE" /> मधून <ph name="TARGET_LANGUAGE" /> मध्ये भाषांतरित करायचे?</translation>
<translation id="5019198164206649151">समर्थन संचयन खराब स्थितीत</translation>
<translation id="5031870354684148875">Google अनुवाद बद्दल</translation>
+<translation id="5045550434625856497">अयोग्य संकेतशब्द</translation>
+<translation id="5087286274860437796">यावेळी सर्व्हरचे प्रमाणपत्र वैध नाही.</translation>
<translation id="5089810972385038852">राज्य</translation>
+<translation id="5094747076828555589">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता प्रमाणपत्र Chromium द्वारे विश्वसनीय नाही. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.</translation>
<translation id="5095208057601539847">प्रांत</translation>
<translation id="5145883236150621069">धोरण प्रतिसादामध्ये त्रुटी कोड अस्तित्वात आहे</translation>
<translation id="5172758083709347301">मशीन</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/> मध्ये नाही? या त्रुटीचा अहवाल नोंदवा</translation>
+<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> मध्ये नाही? या त्रुटीचा अहवाल नोंदवा</translation>
<translation id="5190835502935405962">बुकमार्क बार</translation>
+<translation id="5199729219167945352">प्रयोग</translation>
+<translation id="5251803541071282808">मेघ</translation>
<translation id="5295309862264981122">नॅव्हिगेशनची पुष्टी करा</translation>
<translation id="5299298092464848405">धोरण विश्लेषित करताना त्रुटी</translation>
+<translation id="5316812925700871227">घड्याळाच्या विरुद्ध दिशेने फिरवा</translation>
<translation id="5317780077021120954">जतन करा</translation>
<translation id="536296301121032821">धोरण सेटिंग्ज संचयित करण्यात अयशस्वी</translation>
-<translation id="5439770059721715174">&quot;<ph name="ERROR_PATH"/>&quot; वर स्कीमा प्रमाणीकरण त्रुटी: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">हा सर्व्हर <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता प्रमाणपत्र यावेळी वैध नाही. हे कदाचित चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्ता आपले कनेक्शन आंतरखंडित करीत असल्‍यामुळे होऊ शकते.</translation>
+<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" वर स्कीमा प्रमाणीकरण त्रुटी: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">खराब धोरण टाइमस्टँप</translation>
<translation id="5470861586879999274">&amp;संपादित करा पुन्हा करा</translation>
<translation id="5509780412636533143">व्यवस्थापित केलेले बुकमार्क</translation>
<translation id="5523118979700054094">धोरणाचे नाव</translation>
<translation id="552553974213252141">मजकूर योग्यरितीने काढला होता?</translation>
<translation id="5540224163453853">विनंती केलेला लेख शोधू शकलो नाही.</translation>
+<translation id="5556459405103347317">रीलोड करा</translation>
<translation id="5565735124758917034">सक्रिय</translation>
<translation id="560412284261940334">व्यवस्थापन समर्थित नाही</translation>
<translation id="5629630648637658800">धोरण सेटिंग्ज लोड करण्यात अयशस्वी</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">वर्तमान वापरकर्ता</translation>
<translation id="5813119285467412249">&amp;जोडा पुन्हा करा</translation>
<translation id="5872918882028971132">पालक सूचना</translation>
-<translation id="587701087903783706">मोबाईल-मित्रत्वाचे पृष्‍ठ बंद करा</translation>
<translation id="59107663811261420">कार्डचा हा प्रकार या व्यापार्‍यासाठी Google Payments द्वारे समर्थित नाही. कृपया एक भिन्न कार्ड निवडा.</translation>
+<translation id="5975083100439434680">झूम कमी करा</translation>
<translation id="5989320800837274978">निश्चित प्रॉक्‍सी सर्व्हर किंवा .pac स्क्रिप्ट URL देखील निर्दिष्‍ट केलेली नाही.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">बंद करा</translation>
+<translation id="6060685159320643512">सावधगिरी बाळगा, या प्रयोगांमुळे हानी होऊ शकते</translation>
+<translation id="6151417162996330722">सर्व्हर प्रमाणपत्रास वैधता कालावधी आहे जो खूप मोठा आहे.</translation>
<translation id="6154808779448689242">परत केलेले धोरण टोकन वर्तमान टोकनशी जुळत नाही</translation>
<translation id="6165508094623778733">अधिक जाणून घ्या</translation>
<translation id="6259156558325130047">&amp;पुनर्क्रमित करा पुन्हा करा</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> बुकमार्क</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> बुकमार्क</translation>
<translation id="6282194474023008486">पोस्टल कोड</translation>
<translation id="6337534724793800597">धोरणे नावानुसार फिल्टर करा</translation>
+<translation id="6387478394221739770">छान नवीन Chrome वैशिष्ट्यांमध्ये स्वारस्य आहे? chrome.com/beta वरील आमचे बीटा चॅनेल वापरून पहा.</translation>
+<translation id="6426993025560594914">सर्व प्रयोग आपल्या प्लॅटफॉर्मवर उपलब्ध आहेत!</translation>
<translation id="6445051938772793705">देश</translation>
<translation id="6458467102616083041">धोरणानुसार डीफॉल्ट शोध अक्षम केल्याने दुर्लक्ष करण्‍यात आले.</translation>
<translation id="647261751007945333">डिव्हाइस धोरणे</translation>
<translation id="6512448926095770873">हे पृष्ठ सोडा</translation>
<translation id="6529602333819889595">&amp;पुन्हा करा हटवा</translation>
<translation id="6550675742724504774">पर्याय</translation>
-<translation id="6597614308054261376">आपण <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> पर्यंत पोहोचण्याचा प्रयत्न करीत आहात. यावेळी डेटा बचतकर्त्याद्वारे हे पृष्ठ प्रॉक्सी केले जाऊ शकत नाही.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> शोध</translation>
+<translation id="6597614308054261376">आपण <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर्यंत पोहोचण्याचा प्रयत्न करीत आहात. यावेळी डेटा बचतकर्त्याद्वारे हे पृष्ठ प्रॉक्सी केले जाऊ शकत नाही.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> शोध</translation>
<translation id="6644283850729428850">हे धोरण नापसंत आहे.</translation>
<translation id="6646897916597483132">आपल्या कार्डच्या पुढील भागावर असलेले 4-अंकी CVC प्रविष्ट करा</translation>
+<translation id="674375294223700098">अज्ञात सर्व्हर प्रमाणपत्र त्रुटी.</translation>
<translation id="6753269504797312559">धोरण मूल्य</translation>
<translation id="6831043979455480757">अनुवाद करा</translation>
<translation id="6839929833149231406">क्षेत्र</translation>
<translation id="6874604403660855544">&amp;जोडा पुन्हा करा</translation>
<translation id="6891596781022320156">धोरण स्तर समर्थित नाही.</translation>
<translation id="6915804003454593391">वापरकर्ता:</translation>
-<translation id="6965382102122355670">ठिक आहे</translation>
+<translation id="6957887021205513506">सर्व्हरचे प्रमाणपत्र खोटे असल्याचे दिसून येते.</translation>
+<translation id="6965382102122355670">ठीक आहे</translation>
<translation id="6965978654500191972">डिव्हाइस</translation>
<translation id="6970216967273061347">‍जिल्‍हा</translation>
<translation id="6973656660372572881">निश्चित प्रॉक्सी सर्व्हर आणि .pac स्क्रिप्ट URL निर्दिष्‍ट करण्‍यात आले आहेत.</translation>
<translation id="6980028882292583085">Javascript अ‍ॅलर्ट</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">आपण <ph name="DOMAIN" /> वर पोहोचण्याचा प्रयत्न केला, परंतु सर्व्हरने एक प्रमाणपत्र सादर केले आहे ज्याचा वैधता कालावधी हा विश्वासार्हतेसाठी खूप मोठा आहे.</translation>
<translation id="7087282848513945231">परगणा</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/> मध्ये भाषांतर अयशस्वी झाले.</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" /> मध्ये भाषांतर अयशस्वी झाले.</translation>
<translation id="7139724024395191329">अमिरात</translation>
+<translation id="7179921470347911571">आत्ता पुन्हा लाँच करा </translation>
<translation id="7180611975245234373">रीफ्रेश करा</translation>
<translation id="7182878459783632708">कोणतीही धोरणे सेट नाहीत</translation>
-<translation id="7186367841673660872">हे पृष्ठ<ph name="ORIGINAL_LANGUAGE"/>मधून<ph name="LANGUAGE_LANGUAGE"/>मध्ये अनुवादित केले गेले आहे</translation>
+<translation id="7186367841673660872">हे पृष्ठ<ph name="ORIGINAL_LANGUAGE" />मधून<ph name="LANGUAGE_LANGUAGE" />मध्ये अनुवादित केले गेले आहे</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531"><ph name="SEARCH_TERMS"/> साठी <ph name="SITE_NAME"/> शोधा</translation>
+<translation id="7208899522964477531"><ph name="SEARCH_TERMS" /> साठी <ph name="SITE_NAME" /> शोधा</translation>
+<translation id="725866823122871198">आपल्या संगणकाची तारीख आणि वेळ (<ph name="DATE_AND_TIME" />) चुकीची असल्यामुळे <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> सह खाजगी कनेक्शन स्थापित केले जाऊ शकत नाही.</translation>
<translation id="7275334191706090484">व्यवस्थापित केलेले बुकमार्क</translation>
<translation id="7298195798382681320">शिफारस केलेले</translation>
<translation id="7334320624316649418">&amp;पुनर्क्रमित करा पुन्हा करा</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">अनिवार्य</translation>
<translation id="7542995811387359312">स्वयंचलित क्रेडिट कार्ड भरणे अक्षम झाले आहे कारण हा फॉर्म सुरक्षित कनेक्शन वापरत नाही.</translation>
-<translation id="7568593326407688803">हे पृष्ठ<ph name="ORIGINAL_LANGUAGE"/>मध्ये आहे आपण याचा अनुवाद करु इच्छिता?</translation>
+<translation id="7567204685887185387">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता प्रमाणपत्र कदाचित लबाडीने जारी केले असावे. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.</translation>
+<translation id="7568593326407688803">हे पृष्ठ<ph name="ORIGINAL_LANGUAGE" />मध्ये आहे आपण याचा अनुवाद करु इच्छिता?</translation>
<translation id="7569952961197462199">Chrome मधून क्रेडिट कार्ड काढायचे?</translation>
-<translation id="7600965453749440009">कधीही <ph name="LANGUAGE"/> चा अनुवाद करु नका</translation>
-<translation id="7610193165460212391">मूल्य <ph name="VALUE"/> श्रेणीच्या बाहेर आहे.</translation>
+<translation id="7592362899630581445">सर्व्हरचे प्रमाणपत्र नाव मर्यादांचे उल्लंघन करते.</translation>
+<translation id="7600965453749440009">कधीही <ph name="LANGUAGE" /> चा अनुवाद करु नका</translation>
+<translation id="7610193165460212391">मूल्य <ph name="VALUE" /> श्रेणीच्या बाहेर आहे.</translation>
+<translation id="7674629440242451245">छान नवीन Chrome वैशिष्ट्यांमध्ये स्वारस्य आहे? chrome.com/dev येथे आमचे dev चॅनेल वापरून पहा.</translation>
<translation id="7752995774971033316">व्यवस्थापित न केलेले</translation>
+<translation id="7761701407923456692">सर्व्हरचे प्रमाणपत्र URL शी जुळत नाही.</translation>
<translation id="777702478322588152">परफेक्चुअर</translation>
<translation id="7791543448312431591">जोडा</translation>
<translation id="7805768142964895445">स्थिती</translation>
<translation id="7813600968533626083">Chrome मधून सूचना फॉर्म काढायचा?</translation>
<translation id="7887683347370398519">आपले CVC तपासा आणि पुन्हा प्रयत्न करा</translation>
<translation id="7935318582918952113">DOM डिस्टिलर</translation>
+<translation id="7938958445268990899">सर्व्हरचे प्रमाणपत्र अद्याप वैध नाही.</translation>
<translation id="7956713633345437162">Mobile बुकमार्क</translation>
<translation id="7961015016161918242">कधीही नाही</translation>
<translation id="7977590112176369853">&lt;क्वेरी प्रविष्ट करा&gt;</translation>
-<translation id="7983301409776629893"> नेहमी <ph name="ORIGINAL_LANGUAGE"/> मधून <ph name="TARGET_LANGUAGE"/> मध्ये अनुवाद करा</translation>
+<translation id="7983301409776629893"> नेहमी <ph name="ORIGINAL_LANGUAGE" /> मधून <ph name="TARGET_LANGUAGE" /> मध्ये अनुवाद करा</translation>
<translation id="7988324688042446538">डेस्‍कटॉप बुकमार्क</translation>
<translation id="7995512525968007366">निर्दिष्ट केलेले नाही</translation>
-<translation id="8034522405403831421">हे पृष्‍ठ <ph name="SOURCE_LANGUAGE"/> मध्ये आहे. त्यास <ph name="TARGET_LANGUAGE"/> मध्ये भाषांतरीत करायचे?</translation>
+<translation id="8003882219468422867">एंटरप्राइझ अधिशून्य</translation>
+<translation id="8034522405403831421">हे पृष्‍ठ <ph name="SOURCE_LANGUAGE" /> मध्ये आहे. त्यास <ph name="TARGET_LANGUAGE" /> मध्ये भाषांतरीत करायचे?</translation>
<translation id="8088680233425245692">लेख पाहण्यात अयशस्वी.</translation>
<translation id="8091372947890762290">सक्रियकरण सर्व्हरवर प्रलंबित आहे</translation>
<translation id="8194797478851900357">&amp;हलवा पूर्ववत करा</translation>
-<translation id="8201077131113104583">&quot;<ph name="EXTENSION_ID"/>&quot; ID असलेल्या विस्तारासाठी अवैध अद्यतन URL.</translation>
+<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" ID असलेल्या विस्तारासाठी अवैध अद्यतन URL.</translation>
<translation id="8208216423136871611">जतन करू नका</translation>
<translation id="8218327578424803826">नियुक्त केलेले स्थान:</translation>
<translation id="8249320324621329438">अंतिम प्राप्त केलेले:</translation>
+<translation id="8294431847097064396">स्रोत</translation>
<translation id="8308427013383895095">नेटवर्क कनेक्शनसह समस्या असल्यामुळे अनुवाद अयशस्वी झाला.</translation>
<translation id="8311778656528046050">आपल्याला खात्री आहे की हे पृष्ठ आपण रीलोड करू इच्छिता?</translation>
<translation id="8349305172487531364">बुकमार्क बार</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">यावर लागू होते</translation>
<translation id="8530504477309582336">या प्रकारचे कार्ड Google Payments द्वारे समर्थित नाही. कृपया एक भिन्न कार्ड निवडा.</translation>
<translation id="8553075262323480129">अनुवाद करण्यात अयशस्वी कारण पृष्ठाची भाषा निर्धारित करणे शक्य नाही.</translation>
-<translation id="8571890674111243710"><ph name="LANGUAGE"/> मध्ये पृष्ठ अनुवादित करत आहे...</translation>
+<translation id="8559762987265718583">आपल्या डिव्हाइसची तारीख आणि वेळ (<ph name="DATE_AND_TIME" />) चुकीची असल्याने <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> सह खाजगी कनेक्शन स्थापित केले जाऊ शकले नाही.</translation>
+<translation id="8571890674111243710"><ph name="LANGUAGE" /> मध्ये पृष्ठ अनुवादित करत आहे...</translation>
+<translation id="8647750283161643317">सर्व डीफॉल्टमध्ये रीसेट करा</translation>
<translation id="8713130696108419660">खराब मूळ स्वाक्षरी</translation>
<translation id="8725066075913043281">पुन्हा प्रयत्न करा</translation>
+<translation id="8738058698779197622">एक सुरक्षित कनेक्‍शन स्‍थापित करण्‍यापूर्वी, आपले घड्‍याळ योग्यरित्या सेट केले असणे आवश्यक आहे. कारण वेबसाइट त्यांना स्‍वत:ला ओळखण्‍यासाठी वापरतात ती प्रमाणपत्रे केवळ निर्दिष्‍ट केलेल्‍या कालावधीसाठी वैध असतात. आपल्‍या डिव्‍हाइसचे घड्‍याळ चुकीचे असल्‍यामुळे, Chromium ही प्रमाणपत्रे सत्यापित करू शकत नाही.</translation>
<translation id="8790007591277257123">&amp;पुन्हा करा हटवा</translation>
<translation id="8804164990146287819">गोपनीयता धोरण</translation>
+<translation id="8820817407110198400">Bookmarks</translation>
<translation id="8824019021993735287">Chrome यावेळी आपले कार्ड सत्यापित करण्यात अक्षम होते. कृपया नंतर पुन्हा प्रयत्न करा.</translation>
<translation id="8834246243508017242">संपर्क वापरून स्वयं-भरण सक्षम करा...</translation>
<translation id="883848425547221593">अन्य बुकमार्क</translation>
+<translation id="884923133447025588">कोणतीही निरस्त करण्याची प्रणाली आढळली नाही.</translation>
<translation id="8866481888320382733">धोरण सेटिंग्ज विश्लेषित करताना त्रुटी</translation>
<translation id="8876793034577346603">विश्लेषण करण्यात नेटवर्क कॉन्फिगरेशन अयशस्वी.</translation>
<translation id="8891727572606052622">अवैध प्रॉक्सी मोड.</translation>
-<translation id="8940229512486821554">Run <ph name="EXTENSION_NAME"/> कमांडः <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">क्षमस्व, हा प्रयोग आपल्या प्लॅटफॉर्मवर उपलब्ध नाही.</translation>
+<translation id="8903921497873541725">झूम वाढवा</translation>
+<translation id="8932102934695377596">आपले घड्याळ मागे आहे</translation>
+<translation id="8940229512486821554">Run <ph name="EXTENSION_NAME" /> कमांडः <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">सर्व्हरचे प्रमाणपत्र कालबाह्य झाले आहे.</translation>
<translation id="8988760548304185580">आपल्या कार्डच्या पाठीमागे असलेली कालबाह्यता तारीख आणि 3-अंकी CVC प्रविष्ट करा</translation>
-<translation id="9020542370529661692">हे पृष्ठ <ph name="TARGET_LANGUAGE"/> मध्ये भाषांतरित केले गेले आहे.</translation>
+<translation id="901974403500617787">सिस्टीम-व्याप्त लागू होणारी ध्वजांकने केवळ मालकाद्वारे सेट केली जाऊ शकतात: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">हे पृष्ठ <ph name="TARGET_LANGUAGE" /> मध्ये भाषांतरित केले गेले आहे.</translation>
+<translation id="9049981332609050619">आपण <ph name="DOMAIN" /> वर पोहोचण्याचा प्रयत्न केला, परंतु सर्व्हरने अवैध प्रमाणपत्र सादर केले आहे.</translation>
<translation id="9125941078353557812">आपल्या कार्डच्या पाठीमागे असलेले 3-अंकी CVC प्रविष्ट करा</translation>
<translation id="9137013805542155359">मूळ दर्शवा</translation>
<translation id="9148507642005240123">&amp;संपादित करा पूर्ववत करा</translation>
<translation id="9154176715500758432">या पृष्ठावर राहा</translation>
<translation id="9170848237812810038">&amp;पूर्ववत करा</translation>
+<translation id="917450738466192189">सर्व्हरचे प्रमाणपत्र अवैध आहे.</translation>
+<translation id="9187827965378254003">ओहो, सध्या कोणतेही प्रयोग उपलब्ध नाहीत असे दिसते.</translation>
<translation id="9207861905230894330">लेख जोडण्यात अयशस्वी.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">फॉर्म साफ करा</translation>
+<translation id="988159990683914416">विकसक बिल्ड</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ms.xtb b/chromium/components/strings/components_strings_ms.xtb
index 4b486874865..6855854cd6d 100644
--- a/chromium/components/strings/components_strings_ms.xtb
+++ b/chromium/components/strings/components_strings_ms.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ms">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ms">
+<translation id="1032854598605920125">Putar ikut arah jam</translation>
<translation id="1055184225775184556">&amp;Buat Asal Tambahkan</translation>
<translation id="106701514854093668">Penanda Halaman Desktop</translation>
-<translation id="1103523840287552314">Sentiasa terjemahkan <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Muat ikut lebar</translation>
+<translation id="1103523840287552314">Sentiasa terjemahkan <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Buat asal susun semula</translation>
<translation id="111844081046043029">Adakah anda pasti anda mahu meninggalkan halaman ini?</translation>
<translation id="112840717907525620">Cache dasar OK</translation>
<translation id="1132774398110320017">Tetapan Auto Isi Chrome...</translation>
-<translation id="1152921474424827756">Akses <ph name="BEGIN_LINK"/>salinan cache<ph name="END_LINK"/> <ph name="URL"/></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="1152921474424827756">Akses <ph name="BEGIN_LINK" />salinan cache<ph name="END_LINK" /> <ph name="URL" /></translation>
+<translation id="121201262018556460">Anda cuba untuk mencapai <ph name="DOMAIN" /> , tetapi pelayan memberi sijil yang mengandungi kunci yang lemah, Penyerang mungkin telah merosakkan kunci peribadi dan pelayan tersebut mungkin bukan pelayan yang anda jangkakan (anda mungkin berkomunikasi dengan penyerang).</translation>
<translation id="1227224963052638717">Dasar tidak diketahui.</translation>
<translation id="1227633850867390598">Sembunyikan nilai</translation>
<translation id="1228893227497259893">Pengecam entiti yang salah</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Domain pendaftaran:</translation>
<translation id="1344588688991793829">Tetapan Auto Isi Chromium...</translation>
<translation id="1426410128494586442">Ya</translation>
+<translation id="1430915738399379752">Cetak</translation>
<translation id="1455235771979731432">Terdapat masalah mengesahkan kad anda. Semak sambungan internet anda dan cuba lagi.</translation>
<translation id="1491151370853475546">Muatkan semula Halaman Ini</translation>
<translation id="1549470594296187301">Javascript mesti didayakan untuk menggunakan ciri ini.</translation>
-<translation id="1639239467298939599">Memuatkan</translation>
<translation id="1640180200866533862">Dasar pengguna</translation>
<translation id="1644184664548287040">Konfigurasi rangkaian tidak sah dan tidak boleh diimport.</translation>
-<translation id="1693754753824026215">Halaman di <ph name="SITE"/> menyatakan:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Pelayan ini tidak dapat membuktikan bahawa <ph name="DOMAIN" />; sijil keselamatannya tamat tempoh semalam. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. Jam komputer anda ditetapkan kepada <ph name="CURRENT_DATE" /> pada masa ini. Adakah itu betul? Jika tidak, anda perlu membetulkan jam sistem anda dan kemudian muat semula halaman ini.}other{Pelayan ini tidak dapat membuktikan bahawa <ph name="DOMAIN" />; sijil keselamatannya tamat tempoh # hari yang lalu. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. Jam komputer anda ditetapkan kepada <ph name="CURRENT_DATE" /> pada masa ini. Adakah itu betul? Jika tidak, anda perlu membetulkan jam sistem anda dan kemudian muat semula halaman ini.}}</translation>
+<translation id="168841957122794586">Sijil pelayan mengandungi kunci kriptografi yang lemah.</translation>
+<translation id="1693754753824026215">Halaman di <ph name="SITE" /> menyatakan:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh sistem pengendalian peranti anda. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintasi sambungan anda.</translation>
<translation id="1821930232296380041">Permintaan atau parameter permintaan tidak sah</translation>
-<translation id="1853748787962613237">Gagal memaparkan artikel.</translation>
<translation id="1871208020102129563">Proksi ditetapkan untuk menggunakan pelayan proksi tetap, bukannya URL skrip .pac.</translation>
-<translation id="1875753206475436906">jenis heuristik: <ph name="HEURISTIC_TYPE"/>
- jenis pelayan: <ph name="SERVER_TYPE"/>
- tandatangan medan: <ph name="FIELD_SIGNATURE"/>
- tandatangan borang: <ph name="FORM_SIGNATURE"/>
- id percubaan: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Pergi ke <ph name="LINK"/></translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> Penanda halaman</translation>
+<translation id="194030505837763158">Pergi ke <ph name="LINK" /></translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> Penanda halaman</translation>
<translation id="1973335181906896915">Ralat penyirian</translation>
+<translation id="1974060860693918893">Lanjutan</translation>
<translation id="2025186561304664664">Proksi ditetapkan kepada auto konfigurasi.</translation>
<translation id="2025623846716345241">Sahkan Muat Semula</translation>
-<translation id="2030481566774242610">Adakah anda maksudkan <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Adakah anda maksudkan <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Poskod</translation>
<translation id="20817612488360358">Tetapan proksi sistem telah sedia untuk digunakan tetapi konfigurasi proksi jelas juga telah ditentukan.</translation>
<translation id="2094505752054353250">Domain tidak padan</translation>
<translation id="2096368010154057602">Jabatan</translation>
<translation id="2113977810652731515">Kad</translation>
-<translation id="2114841414352855701">Diabaikan kerana ia telah diatasi oleh <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Diabaikan kerana ia telah diatasi oleh <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Klien Asli</translation>
<translation id="213826338245044447">Penanda Halaman Mudah Alih</translation>
+<translation id="2171101176734966184">Anda cuba untuk mencapai <ph name="DOMAIN" />, tetapi pelayan memberikan sijil yang ditandatangani menggunakan algoritma tandatangan yang lemah. Ini bermakna bahawa bukti kelayakan keselamatan yang diberi pelayan mungkin dipalsukan dan pelayan tersebut bukan seperti yang anda jangkakan (anda mungkin berkomunikasi dengan penyerang).</translation>
<translation id="2181821976797666341">Dasar</translation>
<translation id="2212735316055980242">Dasar tidak dijumpai</translation>
<translation id="2213606439339815911">Mengambil entri…</translation>
<translation id="225207911366869382">Nilai ini tidak lagi digunakan untuk dasar ini.</translation>
<translation id="2262243747453050782">Ralat HTTP</translation>
-<translation id="2270192940992995399">Gagal menemui artikel.</translation>
-<translation id="2328300916057834155">Mengabaikan penanda halaman tidak sah pada indeks <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Eksperimen Tidak Tersedia</translation>
+<translation id="229702904922032456">Sijil akar atau perantara telah tamat tempoh.</translation>
+<translation id="2328300916057834155">Mengabaikan penanda halaman tidak sah pada indeks <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Penanda halaman lain</translation>
<translation id="2359808026110333948">Teruskan</translation>
<translation id="2367567093518048410">Tahap</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="2396249848217231973">&amp;Buat asal pemadaman</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="2455981314101692989">Halaman web ini melumpuhkan pengisian automatik untuk borang ini.</translation>
<translation id="2479410451996844060">URL carian tidak sah.</translation>
+<translation id="2491120439723279231">Sijil pelayan mengandungi ralat.</translation>
<translation id="2495083838625180221">Penghurai JSON</translation>
<translation id="2498091847651709837">Imbas kad baharu</translation>
<translation id="2556876185419854533">&amp;Buat Asal Edit</translation>
-<translation id="2581221116934462656">Adakah anda ingin <ph name="PRODUCT_NAME"/> menawarkan halaman <ph name="LANGUAGE_NAME"/> dari tapak ini diterjemah pada masa akan datang?</translation>
+<translation id="2581221116934462656">Adakah anda ingin <ph name="PRODUCT_NAME" /> menawarkan halaman <ph name="LANGUAGE_NAME" /> dari tapak ini diterjemah pada masa akan datang?</translation>
<translation id="2587841377698384444">ID API Direktori:</translation>
<translation id="2597378329261239068">Dokumen ini dilindungi kata laluan. Sila masukkan kata laluan.</translation>
+<translation id="2625385379895617796">Jam anda lebih awal</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2653659639078652383">Serah</translation>
<translation id="2704283930420550640">Nilai tidak sepadan dengan format.</translation>
<translation id="2721148159707890343">Permintaan berjaya</translation>
+<translation id="2728127805433021124">Sijil pelayan ditandatangani menggunakan algoritma tandatangan yang lemah.</translation>
<translation id="2774256287122201187">Anda boleh teruskan. Jika anda terus ke halaman, amaran ini tidak akan muncul lagi selama lima minit.</translation>
<translation id="277499241957683684">Tiada rekod peranti</translation>
<translation id="2835170189407361413">Kosongkan borang</translation>
-<translation id="2855922900409897335">Mengesahkan <ph name="CREDIT_CARD"/> anda</translation>
+<translation id="2855922900409897335">Mengesahkan <ph name="CREDIT_CARD" /> anda</translation>
+<translation id="2915500479781995473">Pelayan ini tidak dapat membuktikan bahawa ia adalah <ph name="DOMAIN" /> ; sijil keselamatannya tamat tempoh. Ini mungkin disebabkan oleh salah konfigurasi atau penyerang memintas sambungan anda. Jam komputer anda buat masa ini ditetapkan kepada <ph name="CURRENT_TIME" />. Betulkah itu? Jika tidak, anda perlu membetulkan jam sistem anda dan kemudian muatkan semula halaman ini.</translation>
+<translation id="2922350208395188000">Sijil pelayan tidak boleh diperiksa.</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="2958431318199492670">Konfigurasi rangkaian tidak mematuhi piawaian ONC. Sebahagian konfigurasi tidak boleh diimport.</translation>
<translation id="2972581237482394796">&amp;Buat Semula</translation>
-<translation id="3010559122411665027">Masukan senarai &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Masukan senarai "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Jenis dasar salah</translation>
<translation id="3105172416063519923">ID Aset:</translation>
<translation id="3145945101586104090">Gagal menyahkod balasan</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Temui</translation>
<translation id="3174168572213147020">Pulau</translation>
<translation id="3219579145727097045">Masukkan tarikh tamat tempoh dan CVC 4 digit dari bahagian depan kad anda</translation>
-<translation id="3228969707346345236">Gagal terjemah kerana halaman sudah dalam <ph name="LANGUAGE"/>.</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="3228969707346345236">Gagal terjemah kerana halaman sudah dalam <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Buat asal Susun semula</translation>
+<translation id="3286538390144397061">Mulakan Semula Sekarang</translation>
<translation id="333371639341676808">Halang halaman ini daripada mencipta dialog tambahan.</translation>
-<translation id="3369366829301677151">Kemaskinikan dan sahkan <ph name="CREDIT_CARD"/> anda</translation>
+<translation id="3340978935015468852">tetapan</translation>
+<translation id="3369192424181595722">Ralat Jam</translation>
+<translation id="3369366829301677151">Kemaskinikan dan sahkan <ph name="CREDIT_CARD" /> anda</translation>
<translation id="337363190475750230">Nyahperuntukkan</translation>
<translation id="3377188786107721145">Ralat menghuraikan dasar</translation>
<translation id="3380365263193509176">Ralat tidak diketahui</translation>
<translation id="3380864720620200369">ID Pelanggan:</translation>
<translation id="3427342743765426898">&amp;Buat Semula Edit</translation>
+<translation id="3435896845095436175">Dayakan</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Selang masa ambil:</translation>
+<translation id="3462200631372590220">Menyembunyikan butiran</translation>
+<translation id="3528171143076753409">Sijil pelayan tidak dipercayai.</translation>
<translation id="3542684924769048008">Gunakan kata laluan untuk:</translation>
<translation id="3583757800736429874">&amp;Buat Semula Pindahkan</translation>
<translation id="3623476034248543066">Tunjukkan nilai</translation>
+<translation id="3648607100222897006">Ciri percubaan ini mungkin berubah, pecah atau hilang pada bila-bila masa. Kami sama sekali tidak menjamin mengenai apa yang akan berlaku jika anda menghidupkan salah satu percubaan ini, dan penyemak imbas anda juga mungkin terbakar secara spontan. Saya tidak melawak, penyemak imbas anda boleh memadamkan semua data, atau keselamatan dan privasi anda boleh terjejas dalam cara yang tidak dijangka. Sebarang percubaan yang anda dayakan akan dilumpuhkan untuk semua pengguna penyemak imbas ini. Sila teruskan dengan berhati-hati.</translation>
<translation id="3650584904733503804">Pengesahan berjaya</translation>
<translation id="370665806235115550">Memuatkan...</translation>
<translation id="3712624925041724820">Kehabisan lesen</translation>
<translation id="3739623965217189342">Pautan yang anda salin</translation>
<translation id="375403751935624634">Gagal menterjemah disebabkan ralat pelayan.</translation>
<translation id="385051799172605136">Kembali</translation>
+<translation id="3858027520442213535">Kemas kini tarikh dan masa</translation>
<translation id="3884278016824448484">Pengecam peranti bercanggah</translation>
<translation id="3885155851504623709">Mukim</translation>
<translation id="3934680773876859118">Gagal untuk memuatkan dokumen PDF</translation>
<translation id="3963721102035795474">Mod Pembaca</translation>
<translation id="4030383055268325496">&amp;Buat asal tambahkan</translation>
-<translation id="4058922952496707368">Kekunci &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">AMARAN</translation>
+<translation id="4058922952496707368">Kekunci "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Konfigurasi proksi ditetapkan kepada penggunaaan URL skrip .pac, bukannya pelayan proksi tetap.</translation>
<translation id="409504436206021213">Jangan Muat Semula</translation>
<translation id="4103249731201008433">Nombor siri peranti tidak sah</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Tandatangan tidak elok</translation>
<translation id="4269787794583293679">(Tiada nama pengguna)</translation>
<translation id="4300246636397505754">Cadangan ibu bapa</translation>
-<translation id="4372948949327679948">Nilai <ph name="VALUE_TYPE"/> yang dijangka.</translation>
+<translation id="4325863107915753736">Gagal menemui artikel</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="4394049700291259645">Lumpuhkan</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="443673843213245140">Penggunaan proksi dilumpuhkan tetapi konfigurasi proksi yang jelas dinyatakan.</translation>
-<translation id="4506176782989081258">Ralat pengesahan: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Ralat pengesahan: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Alih keluar alamat daripada Chrome?</translation>
<translation id="4594403342090139922">&amp;Buat asal Pemadaman</translation>
<translation id="4607653538520819196">Halaman ini tidak boleh diproksikan oleh Penjimat Data.</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="4726672564094551039">Muat semula dasar</translation>
+<translation id="4728558894243024398">Platform</translation>
+<translation id="4771973620359291008">Ralat tidak diketahui telah berlaku.</translation>
<translation id="4800132727771399293">Semak tarikh tamat tempoh serta CVC anda dan cuba lagi</translation>
<translation id="4813512666221746211">Ralat rangkaian</translation>
+<translation id="4816492930507672669">Muat halaman</translation>
<translation id="4850886885716139402">Lihat</translation>
-<translation id="4923417429809017348">Halaman ini diterjemahkan dari bahasa yang tidak diketahui ke <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Halaman ini diterjemahkan dari bahasa yang tidak diketahui ke <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Mesti ditentukan.</translation>
<translation id="4968547170521245791">Tidak boleh Proksi</translation>
-<translation id="498957508165411911">Terjemahkan daripada <ph name="ORIGINAL_LANGUAGE"/> kepada <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Terjemahkan daripada <ph name="ORIGINAL_LANGUAGE" /> kepada <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Simpanan penyandaran dalam keadaan buruk</translation>
-<translation id="5031870354684148875">Mengenai Terjemahan Google</translation>
+<translation id="5031870354684148875">Perihal Google Terjemah</translation>
+<translation id="5045550434625856497">Kata laluan tidak sah</translation>
+<translation id="5087286274860437796">Sijil pelayan tidak sah pada masa ini.</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="5145883236150621069">Terdapat kod ralat dalam balasan dasar</translation>
<translation id="5172758083709347301">Mesin</translation>
-<translation id="5179510805599951267">Bukan dalam <ph name="ORIGINAL_LANGUAGE"/>? Laporkan ralat ini</translation>
+<translation id="5179510805599951267">Bukan dalam <ph name="ORIGINAL_LANGUAGE" />? Laporkan ralat ini</translation>
<translation id="5190835502935405962">Bar Penanda Halaman</translation>
+<translation id="5199729219167945352">Eksperimen</translation>
+<translation id="5251803541071282808">Awan</translation>
<translation id="5295309862264981122">Sahkan Navigasi</translation>
<translation id="5299298092464848405">Ralat semasa menghuraikan dasar</translation>
+<translation id="5316812925700871227">Putar lawan arah jam</translation>
<translation id="5317780077021120954">Simpan</translation>
<translation id="536296301121032821">Gagal menyimpan tetapan dasar</translation>
-<translation id="5439770059721715174">Ralat pengesahan skema di &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Ralat pengesahan skema di "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Cap waktu dasar tidak elok</translation>
<translation id="5470861586879999274">&amp;Buat semula edit</translation>
<translation id="5509780412636533143">Penanda halaman terurus</translation>
<translation id="5523118979700054094">Nama dasar</translation>
<translation id="552553974213252141">Adakah teks diekstrak dengan betul?</translation>
<translation id="5540224163453853">Tidak menemui artikel yang diminta.</translation>
+<translation id="5556459405103347317">Muat Semula</translation>
<translation id="5565735124758917034">Aktif</translation>
<translation id="560412284261940334">Pengurusan tidak disokong</translation>
<translation id="5629630648637658800">Gagal memuatkan tetapan dasar</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Pengguna semasa</translation>
<translation id="5813119285467412249">&amp;Buat Semula Tambahkan</translation>
<translation id="5872918882028971132">Cadangan Ibu Bapa</translation>
-<translation id="587701087903783706">Tutup paparan mesra mudah alih</translation>
<translation id="59107663811261420">Kad jenis ini tidak disokong oleh Google Payments untuk pedagang ini. Sila pilih kad yang lain.</translation>
+<translation id="5975083100439434680">Zum keluar</translation>
<translation id="5989320800837274978">Pelayan proksi tetap begitu juga URL skrip .pac, kedua-duanya tidak ditetapkan.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Tutup</translation>
+<translation id="6060685159320643512">Berhati-hati, percubaan ini mungkin memudaratkan</translation>
+<translation id="6151417162996330722">Sijil pelayan mempunyai tempoh sah yang terlalu panjang.</translation>
<translation id="6154808779448689242">Token dasar yang dikembalikan tidak sepadan dengan token semasa</translation>
<translation id="6165508094623778733">Ketahui lebih lanjut</translation>
<translation id="6259156558325130047">&amp;Buat Asal Susun Semula</translation>
-<translation id="6263376278284652872">Penanda halaman <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Penanda halaman <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Poskod</translation>
<translation id="6337534724793800597">Tapis dasar mengikut nama</translation>
+<translation id="6387478394221739770">Berminat dengan ciri Chrome baharu yang hebat? Cuba saluran beta kami di chrome.com/beta.</translation>
+<translation id="6426993025560594914">Semua eksperimen boleh didapati pada platform anda!</translation>
<translation id="6445051938772793705">Negara</translation>
<translation id="6458467102616083041">Diabaikan kerana carian lalai dilumpuhkan oleh dasar.</translation>
<translation id="647261751007945333">Dasar peranti</translation>
<translation id="6512448926095770873">Tinggalkan Halaman ini</translation>
<translation id="6529602333819889595">&amp;Buat Semula Pemadaman</translation>
<translation id="6550675742724504774">Pilihan</translation>
-<translation id="6597614308054261376">Anda sedang cuba menghubungi <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Halaman ini tidak boleh diproksikan oleh Penjimat Data pada masa ini.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Carian</translation>
+<translation id="6597614308054261376">Anda sedang cuba menghubungi <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Halaman ini tidak boleh diproksikan oleh Penjimat Data pada masa ini.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Carian</translation>
<translation id="6644283850729428850">Dasar ini telah dikecam.</translation>
<translation id="6646897916597483132">Masukkan CVC 4 digit dari bahagian depan kad anda</translation>
+<translation id="674375294223700098">Ralat sijil pelayan tidak diketahui.</translation>
<translation id="6753269504797312559">Nilai dasar</translation>
<translation id="6831043979455480757">Terjemah</translation>
<translation id="6839929833149231406">Kawasan</translation>
<translation id="6874604403660855544">&amp;Buat semula tambahkan</translation>
<translation id="6891596781022320156">Tahap dasar tidak disokong.</translation>
<translation id="6915804003454593391">Pengguna:</translation>
+<translation id="6957887021205513506">Sijil pelayan rupanya adalah pemalsuan.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">Makluman Javascript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Anda cuba untuk mencapai <ph name="DOMAIN" />, tetapi pelayan memberikan sijil yang tempoh sahnya terlalu panjang untuk boleh dipercayai.</translation>
<translation id="7087282848513945231">Daerah</translation>
-<translation id="7108649287766967076">Terjemahan kepada <ph name="TARGET_LANGUAGE"/> gagal.</translation>
+<translation id="7108649287766967076">Terjemahan kepada <ph name="TARGET_LANGUAGE" /> gagal.</translation>
<translation id="7139724024395191329">Emiriah</translation>
+<translation id="7179921470347911571">Lancarkan Semula Sekarang</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="7186367841673660872">Halaman ini telah diterjemahkan dari<ph name="ORIGINAL_LANGUAGE" />ke<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Cari <ph name="SITE_NAME"/> untuk <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Cari <ph name="SITE_NAME" /> untuk <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Sambungan peribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak boleh diwujudkan kerana tarikh dan masa komputer anda (<ph name="DATE_AND_TIME" />) tidak betul.</translation>
<translation id="7275334191706090484">Penanda Halaman Terurus</translation>
<translation id="7298195798382681320">Disyorkan</translation>
<translation id="7334320624316649418">&amp;Buat semula susun semula</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Wajib</translation>
<translation id="7542995811387359312">Pengisian kad kredit automatik dilumpuhkan kerana borang ini tidak menggunakan sambungan selamat.</translation>
-<translation id="7568593326407688803">Halaman ini adalah dalam<ph name="ORIGINAL_LANGUAGE"/>Adakah anda ingin menterjemahkannya?</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="7568593326407688803">Halaman ini adalah dalam<ph name="ORIGINAL_LANGUAGE" />Adakah anda ingin menterjemahkannya?</translation>
<translation id="7569952961197462199">Alih keluar kad kredit daripada Chrome?</translation>
-<translation id="7600965453749440009">Jangan sekali-kali terjemahkan <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Nilai berada di luar julat <ph name="VALUE"/></translation>
+<translation id="7592362899630581445">Sijil pelayan melanggar kekangan nama.</translation>
+<translation id="7600965453749440009">Jangan sekali-kali terjemahkan <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Nilai berada di luar julat <ph name="VALUE" /></translation>
+<translation id="7674629440242451245">Berminat dengan ciri Chrome baharu yang hebat? Cuba saluran pembangun kami di chrome.com/dev.</translation>
<translation id="7752995774971033316">Tidak Diurus</translation>
+<translation id="7761701407923456692">Sijil pelayan tidak sepadan dengan URL.</translation>
<translation id="777702478322588152">Wilayah</translation>
<translation id="7791543448312431591">Tambah</translation>
<translation id="7805768142964895445">Status</translation>
<translation id="7813600968533626083">Alih keluar cadangan borang daripada Chrome?</translation>
<translation id="7887683347370398519">Semak CVC anda dan cuba lagi</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Sijil pelayan masih belum sah.</translation>
<translation id="7956713633345437162">Penanda halaman mudah alih</translation>
<translation id="7961015016161918242">Tidak sama sekali</translation>
<translation id="7977590112176369853">&lt;masukkan pertanyaan&gt;</translation>
-<translation id="7983301409776629893">Sentiasa terjemahkan <ph name="ORIGINAL_LANGUAGE"/> ke <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Sentiasa terjemahkan <ph name="ORIGINAL_LANGUAGE" /> ke <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Penanda halaman desktop</translation>
<translation id="7995512525968007366">Tidak Ditentukan</translation>
-<translation id="8034522405403831421">Halaman ini dalam <ph name="SOURCE_LANGUAGE"/>. Terjemahkannya kepada <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Pembatalan perusahaan</translation>
+<translation id="8034522405403831421">Halaman ini dalam <ph name="SOURCE_LANGUAGE" />. Terjemahkannya kepada <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Gagal melihat artikel.</translation>
<translation id="8091372947890762290">Pengaktifan belum selesai pada pelayan</translation>
<translation id="8194797478851900357">&amp;Buat Asal Pindahkan</translation>
-<translation id="8201077131113104583">URL kemas kini tidak sah untuk sambungan dengan ID &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">URL kemas kini tidak sah untuk sambungan dengan ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Jangan simpan</translation>
<translation id="8218327578424803826">Lokasi yang Ditentukan:</translation>
<translation id="8249320324621329438">Diambil kali terakhir:</translation>
+<translation id="8294431847097064396">Sumber</translation>
<translation id="8308427013383895095">Gagal terjemahan kerana masalah dengan sambungan rangkaian.</translation>
<translation id="8311778656528046050">Adakah anda pasti mahu memuat semula halaman ini?</translation>
<translation id="8349305172487531364">Bar penanda halaman</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Diguna pakai untuk</translation>
<translation id="8530504477309582336">Kad jenis ini tidak disokong oleh Google Payments. Sila pilih kad yang lain.</translation>
<translation id="8553075262323480129">Gagal terjemahan kerana bahasa halaman tidak dapat ditentukan.</translation>
-<translation id="8571890674111243710">Menterjemah halaman ke <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Sambungan peribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak boleh diwujudkan kerana tarikh dan masa peranti anda (<ph name="DATE_AND_TIME" />) tidak betul.</translation>
+<translation id="8571890674111243710">Menterjemah halaman ke <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Tetapkan semula semua kepada lalai</translation>
<translation id="8713130696108419660">Tandatangan parap tidak elok</translation>
<translation id="8725066075913043281">Cuba lagi</translation>
+<translation id="8738058698779197622">Untuk mewujudkan sambungan yang selamat, jam anda perlu ditetapkan dengan betul. Ini kerana sijil yang digunakan oleh tapak web untuk mengenal pastinya hanya sah untuk tempoh masa yang tertentu. Memandangkan jam peranti anda tidak betul, Chromium tidak boleh mengesahkan sijil-sijil ini.</translation>
<translation id="8790007591277257123">&amp;Buat semula pemadaman</translation>
<translation id="8804164990146287819">Dasar Privasi</translation>
+<translation id="8820817407110198400">Penanda buku</translation>
<translation id="8824019021993735287">Chrome tidak dapat mengesahkan kad anda pada masa ini. Sila cuba lagi kemudian.</translation>
<translation id="8834246243508017242">Dayakan Auto-Isian menggunakan Kenalan ...</translation>
<translation id="883848425547221593">Penanda Halaman Lain</translation>
+<translation id="884923133447025588">Tiada mekanisme pembatalan dijumpai.</translation>
<translation id="8866481888320382733">Ralat semasa menghuraikan tetapan dasar</translation>
<translation id="8876793034577346603">Konfigurasi rangkaian gagal dihuraikan.</translation>
<translation id="8891727572606052622">Mod proksi tidak sah.</translation>
-<translation id="8940229512486821554">Jalankan perintah <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Maaf, eksperimen ini tidak tersedia pada platform anda.</translation>
+<translation id="8903921497873541725">Zum masuk</translation>
+<translation id="8932102934695377596">Jam anda di belakang</translation>
+<translation id="8940229512486821554">Jalankan perintah <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Sijil pelayan telah tamat tempoh.</translation>
<translation id="8988760548304185580">Masukkan tarikh tamat tempoh dan CVC 3 digit dari bahagian belakang kad anda</translation>
-<translation id="9020542370529661692">Halaman ini telah diterjemahkan kepada <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Bendera yang diguna pakai di seluruh sistem hanya boleh ditetapkan oleh pemilik: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Halaman ini telah diterjemahkan kepada <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Anda cuba untuk mencapai <ph name="DOMAIN" />, tetapi pelayan memberikan sijil tidak sah.</translation>
<translation id="9125941078353557812">Masukkan CVC 3 digit dari bahagian belakang kad anda</translation>
<translation id="9137013805542155359">Paparkan asal</translation>
<translation id="9148507642005240123">&amp;Buat asal edit</translation>
<translation id="9154176715500758432">Kekal di Halaman ini</translation>
<translation id="9170848237812810038">&amp;Buat asal</translation>
+<translation id="917450738466192189">Sijil pelayan tidak sah.</translation>
+<translation id="9187827965378254003">Oh, nampaknya tiada eksperimen tersedia pada masa ini.</translation>
<translation id="9207861905230894330">Gagal menambahkan artikel.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">KOSONGKAN BORANG</translation>
+<translation id="988159990683914416">Binaan Pemaju</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_nl.xtb b/chromium/components/strings/components_strings_nl.xtb
index b260c7ec4df..a54ecceabd8 100644
--- a/chromium/components/strings/components_strings_nl.xtb
+++ b/chromium/components/strings/components_strings_nl.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="nl">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="nl">
+<translation id="1032854598605920125">Rechtsom draaien</translation>
<translation id="1055184225775184556">&amp;Toevoegen ongedaan maken</translation>
<translation id="106701514854093668">Desktopbladwijzers</translation>
-<translation id="1103523840287552314"><ph name="LANGUAGE"/> altijd vertalen</translation>
+<translation id="1080116354587839789">Aanpassen aan breedte</translation>
+<translation id="1103523840287552314"><ph name="LANGUAGE" /> altijd vertalen</translation>
<translation id="1113869188872983271">&amp;Volgorde wijzigen ongedaan maken</translation>
<translation id="111844081046043029">Pagina verlaten?</translation>
<translation id="112840717907525620">Cachegeheugen van beleid is OK</translation>
<translation id="1132774398110320017">Instellingen voor automatisch aanvullen in Chrome...</translation>
-<translation id="1152921474424827756">Een <ph name="BEGIN_LINK"/>gecacht exemplaar<ph name="END_LINK"/> van <ph name="URL"/> openen</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="1152921474424827756">Een <ph name="BEGIN_LINK" />gecacht exemplaar<ph name="END_LINK" /> van <ph name="URL" /> openen</translation>
+<translation id="121201262018556460">Je probeert <ph name="DOMAIN" /> te bereiken, maar de server heeft een certificaat geretourneerd met een zwakke sleutel. Een hacker kan de persoonlijke sleutel hebben aangepast en het is mogelijk dat de server zelf een imitatie is (wellicht een server die je schade probeert te berokkenen).</translation>
<translation id="1227224963052638717">Onbekend beleid.</translation>
<translation id="1227633850867390598">Waarde verbergen</translation>
<translation id="1228893227497259893">Onjuiste entiteits-ID</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Inschrijvingsdomein:</translation>
<translation id="1344588688991793829">Instellingen voor automatisch aanvullen in Chromium...</translation>
<translation id="1426410128494586442">Ja</translation>
+<translation id="1430915738399379752">Afdrukken</translation>
<translation id="1455235771979731432">Er is een probleem opgetreden bij het verifiëren van je kaart. Controleer je internetverbinding en probeer het opnieuw.</translation>
<translation id="1491151370853475546">Deze pagina opnieuw laden</translation>
<translation id="1549470594296187301">JavaScript moet zijn ingeschakeld om deze functie te kunnen gebruiken.</translation>
-<translation id="1639239467298939599">Laden</translation>
<translation id="1640180200866533862">Gebruikersbeleid</translation>
<translation id="1644184664548287040">De netwerkconfiguratie is ongeldig en kan niet worden geïmporteerd.</translation>
-<translation id="1693754753824026215">De pagina op <ph name="SITE"/> meldt het volgende:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het bijbehorende beveiligingscertificaat is gisteren verlopen. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. De klok van je computer is momenteel ingesteld op <ph name="CURRENT_DATE" />. Is dat correct? Zo niet, dan moet je de klok van je systeem aanpassen en vervolgens deze pagina vernieuwen.}other{Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het bijbehorende beveiligingscertificaat is # dagen geleden verlopen. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. De klok van je computer is momenteel ingesteld op <ph name="CURRENT_DATE" />. Is dat correct? Zo niet, dan moet je de klok van je systeem aanpassen en vervolgens deze pagina vernieuwen.}}</translation>
+<translation id="168841957122794586">Het servercertificaat bevat een zwakke cryptografische sleutel.</translation>
+<translation id="1693754753824026215">De pagina op <ph name="SITE" /> meldt het volgende:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server wordt niet vertrouwd door het besturingssysteem van je apparaat. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
<translation id="1821930232296380041">Ongeldige aanvraag of aanvraagparameters</translation>
-<translation id="1853748787962613237">Kan artikel niet weergeven.</translation>
<translation id="1871208020102129563">Proxy is ingesteld op het gebruik van vaste proxyservers, niet op een script-URL van het PAC-type.</translation>
-<translation id="1875753206475436906">heuristisch type: <ph name="HEURISTIC_TYPE"/>
- servertype: <ph name="SERVER_TYPE"/>
- veldhandtekening: <ph name="FIELD_SIGNATURE"/>
- formulierhandtekening: <ph name="FORM_SIGNATURE"/>
- experiment-id: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Ga naar <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Bladwijzers voor <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Ga naar <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Bladwijzers voor <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Serialisatiefout</translation>
+<translation id="1974060860693918893">Geavanceerd</translation>
<translation id="2025186561304664664">Proxy is ingesteld op automatische configuratie.</translation>
<translation id="2025623846716345241">Opnieuw laden bevestigen</translation>
-<translation id="2030481566774242610">Bedoelde je <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Bedoelde je <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Postcode</translation>
<translation id="20817612488360358">De proxyinstellingen van het systeem moeten worden gebruikt, maar er is ook een expliciete proxyconfiguratie opgegeven.</translation>
<translation id="2094505752054353250">Domeinen komen niet overeen</translation>
<translation id="2096368010154057602">Departement</translation>
<translation id="2113977810652731515">Kaart</translation>
-<translation id="2114841414352855701">Genegeerd omdat het werd overschreven door <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Genegeerd omdat het werd overschreven door <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Mobiele bladwijzers</translation>
+<translation id="2171101176734966184">Je probeert <ph name="DOMAIN" /> te bereiken. De server heeft echter een certificaat geretourneerd dat een zwak ondertekeningsalgoritme gebruikt. Dit houdt in dat de betrouwbaarheidsverklaring van de server kan zijn vervalst. Het is mogelijk dat de server zelf een imitatie is (wellicht een server die je schade probeert te berokkenen).</translation>
<translation id="2181821976797666341">Beleid</translation>
<translation id="2212735316055980242">Beleid niet gevonden</translation>
<translation id="2213606439339815911">Items ophalen…</translation>
<translation id="225207911366869382">Deze waarde is verouderd voor dit beleid.</translation>
<translation id="2262243747453050782">HTTP-fout</translation>
-<translation id="2270192940992995399">Kan artikel niet vinden.</translation>
-<translation id="2328300916057834155">Ongeldige bladwijzer genegeerd bij index <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Onbeschikbare experimenten</translation>
+<translation id="229702904922032456">Een root- of tussenliggend certificaat is verlopen.</translation>
+<translation id="2328300916057834155">Ongeldige bladwijzer genegeerd bij index <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Andere bladwijzers</translation>
<translation id="2359808026110333948">Doorgaan</translation>
<translation id="2367567093518048410">Niveau</translation>
+<translation id="2384307209577226199">Standaardinstelling van bedrijf</translation>
+<translation id="2386255080630008482">Het servercertificaat is ingetrokken.</translation>
<translation id="2392959068659972793">Beleid weergeven zonder waarde ingesteld</translation>
<translation id="2396249848217231973">&amp;Verwijderen ongedaan maken</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="2455981314101692989">Deze webpagina heeft Automatisch aanvullen uitgeschakeld voor dit formulier.</translation>
<translation id="2479410451996844060">Ongeldige zoek-URL.</translation>
+<translation id="2491120439723279231">Het servercertificaat bevat fouten.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2498091847651709837">Nieuwe kaart scannen</translation>
<translation id="2556876185419854533">&amp;Bewerken ongedaan maken</translation>
-<translation id="2581221116934462656">Wil je dat <ph name="PRODUCT_NAME"/> de pagina's op deze site die in het <ph name="LANGUAGE_NAME"/> zijn geschreven, voortaan vertaalt?</translation>
+<translation id="2581221116934462656">Wil je dat <ph name="PRODUCT_NAME" /> de pagina's op deze site die in het <ph name="LANGUAGE_NAME" /> zijn geschreven, voortaan vertaalt?</translation>
<translation id="2587841377698384444">Directory API-ID:</translation>
<translation id="2597378329261239068">Dit document is beveiligd met een wachtwoord. Geef een wachtwoord op.</translation>
+<translation id="2625385379895617796">Je klok loopt voor</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2653659639078652383">Verzenden</translation>
<translation id="2704283930420550640">Waarde komt niet overeen met notatie.</translation>
<translation id="2721148159707890343">Verzoek geslaagd</translation>
+<translation id="2728127805433021124">Het certificaat van de server is ondertekend met een zwak ondertekeningsalgoritme.</translation>
<translation id="2774256287122201187">Je kunt doorgaan. Als je doorgaat naar de pagina, wordt deze waarschuwing gedurende vijf minuten niet opnieuw weergegeven.</translation>
<translation id="277499241957683684">Apparaatrecord ontbreekt</translation>
<translation id="2835170189407361413">Formulier leegmaken</translation>
-<translation id="2855922900409897335">Je <ph name="CREDIT_CARD"/> verifiëren</translation>
+<translation id="2855922900409897335">Je <ph name="CREDIT_CARD" /> verifiëren</translation>
+<translation id="2915500479781995473">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server is verlopen. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. De klok van je computer is momenteel ingesteld op <ph name="CURRENT_TIME" />. Klopt dat? Zo niet, dan moet je de klok van het systeem corrigeren en deze pagina vernieuwen.</translation>
+<translation id="2922350208395188000">Het servercertificaat kan niet worden gecontroleerd.</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="2958431318199492670">De netwerkconfiguratie voldoet niet aan de ONC-standaard. Delen van de configuratie worden mogelijk niet geïmporteerd.</translation>
<translation id="2972581237482394796">&amp;Opnieuw</translation>
-<translation id="3010559122411665027">Lijstitem '<ph name="ENTRY_INDEX"/>': <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Lijstitem '<ph name="ENTRY_INDEX" />': <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Onjuist beleidstype</translation>
<translation id="3105172416063519923">Item-ID:</translation>
<translation id="3145945101586104090">Kan reactie niet decoderen</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Eiland</translation>
<translation id="3219579145727097045">Geef de vervaldatum en viercijferige CVC-code op die op de voorkant van je kaart staan</translation>
-<translation id="3228969707346345236">De vertaling is mislukt omdat de pagina al in het <ph name="LANGUAGE"/> is.</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="3228969707346345236">De vertaling is mislukt omdat de pagina al in het <ph name="LANGUAGE" /> is.</translation>
<translation id="3270847123878663523">&amp;Volgorde wijzigen ongedaan maken</translation>
+<translation id="3286538390144397061">Nu herstarten</translation>
<translation id="333371639341676808">Voorkom dat deze pagina extra dialoogvensters weergeeft.</translation>
-<translation id="3369366829301677151">Je <ph name="CREDIT_CARD"/> updaten en verifiëren</translation>
+<translation id="3340978935015468852">instellingen</translation>
+<translation id="3369192424181595722">Klokfout</translation>
+<translation id="3369366829301677151">Je <ph name="CREDIT_CARD" /> updaten en verifiëren</translation>
<translation id="337363190475750230">Uitgeschreven</translation>
<translation id="3377188786107721145">Fout bij het parseren van beleid</translation>
<translation id="3380365263193509176">Onbekende fout</translation>
<translation id="3380864720620200369">Klant-ID:</translation>
<translation id="3427342743765426898">&amp;Opnieuw bewerken</translation>
+<translation id="3435896845095436175">Inschakelen</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Ophaalinterval:</translation>
+<translation id="3462200631372590220">Gedetailleerde informatie verbergen</translation>
+<translation id="3528171143076753409">Het servercertificaat is niet betrouwbaar.</translation>
<translation id="3542684924769048008">Wachtwoord gebruiken voor:</translation>
<translation id="3583757800736429874">&amp;Opnieuw verplaatsen</translation>
<translation id="3623476034248543066">Waarde weergeven</translation>
+<translation id="3648607100222897006">Deze experimentele functies kunnen op elk moment worden aangepast, vastlopen of verdwijnen. We bieden geen enkele garantie aangaande wat er gebeurt als je een van deze experimenten inschakelt: je browser kan zelfs spontaan in brand vliegen. Alle gekheid op een stokje, het is mogelijk dat alle gegevens in je browser worden gewist, of dat je veiligheid en privacy op onverwachte manieren risico lopen. Experimenten die je inschakelt, worden ingeschakeld voor alle gebruikers van deze browser. Let dus goed op wat je doet.</translation>
<translation id="3650584904733503804">Validatie geslaagd</translation>
<translation id="370665806235115550">Laden...</translation>
<translation id="3712624925041724820">Licenties zijn verbruikt</translation>
<translation id="3739623965217189342">Link die je hebt gekopieerd</translation>
<translation id="375403751935624634">Het vertalen is mislukt wegens een serverfout.</translation>
<translation id="385051799172605136">Vorige</translation>
+<translation id="3858027520442213535">Datum en tijd updaten</translation>
<translation id="3884278016824448484">Conflicterende apparaat-ID's</translation>
<translation id="3885155851504623709">Gemeente</translation>
<translation id="3934680773876859118">PDF-document kan niet worden geladen</translation>
<translation id="3963721102035795474">Lezermodus</translation>
<translation id="4030383055268325496">&amp;Toevoegen ongedaan maken</translation>
-<translation id="4058922952496707368">Sleutel '<ph name="SUBKEY"/>': <ph name="ERROR"/></translation>
+<translation id="404928562651467259">WAARSCHUWING</translation>
+<translation id="4058922952496707368">Sleutel '<ph name="SUBKEY" />': <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Proxyconfiguratie is ingesteld op het gebruik van een pac-script-URL, niet op het gebruik van vaste proxyservers.</translation>
<translation id="409504436206021213">Niet opnieuw laden</translation>
<translation id="4103249731201008433">Serienummer van apparaat is ongeldig</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Onjuiste handtekening</translation>
<translation id="4269787794583293679">(Geen gebruikersnaam)</translation>
<translation id="4300246636397505754">Bovenliggende suggesties</translation>
-<translation id="4372948949327679948">Verwachte <ph name="VALUE_TYPE"/> waarde.</translation>
+<translation id="4325863107915753736">Kan artikel niet vinden</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="4394049700291259645">Uitschakelen</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="443673843213245140">Het gebruik van een proxy is uitgeschakeld, maar er is wel een expliciete proxyconfiguratie opgegeven.</translation>
-<translation id="4506176782989081258">Validatiefout: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Validatiefout: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Adres verwijderen uit Chrome?</translation>
<translation id="4594403342090139922">&amp;Verwijderen ongedaan maken</translation>
<translation id="4607653538520819196">Deze pagina kan niet via proxy worden overgedragen door Databesparing.</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="4726672564094551039">Beleid opnieuw laden</translation>
+<translation id="4728558894243024398">Platform</translation>
+<translation id="4771973620359291008">Er is een onbekende fout opgetreden.</translation>
<translation id="4800132727771399293">Controleer je vervaldatum en CVC-code en probeer het opnieuw</translation>
<translation id="4813512666221746211">Netwerkfout</translation>
+<translation id="4816492930507672669">Aanpassen aan pagina</translation>
<translation id="4850886885716139402">Weergave</translation>
-<translation id="4923417429809017348">Deze pagina is vertaald uit een onbekende taal naar het <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Deze pagina is vertaald uit een onbekende taal naar het <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Moet worden opgegeven.</translation>
<translation id="4968547170521245791">Kan niet overdragen via proxy</translation>
-<translation id="498957508165411911">Vertalen uit het <ph name="ORIGINAL_LANGUAGE"/> naar het <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Vertalen uit het <ph name="ORIGINAL_LANGUAGE" /> naar het <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Backend-opslag in slechte staat</translation>
<translation id="5031870354684148875">Over Google Translate</translation>
+<translation id="5045550434625856497">Onjuist wachtwoord</translation>
+<translation id="5087286274860437796">Het servercertificaat is momenteel niet geldig.</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="5145883236150621069">Foutcode aanwezig in de beleidsreactie</translation>
<translation id="5172758083709347301">Computer</translation>
-<translation id="5179510805599951267">Niet in het <ph name="ORIGINAL_LANGUAGE"/>? Deze fout melden</translation>
+<translation id="5179510805599951267">Niet in het <ph name="ORIGINAL_LANGUAGE" />? Deze fout melden</translation>
<translation id="5190835502935405962">Bladwijzerbalk</translation>
+<translation id="5199729219167945352">Experimenten</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">Navigatie bevestigen</translation>
<translation id="5299298092464848405">Fout bij het parseren van het beleid</translation>
+<translation id="5316812925700871227">Linksom draaien</translation>
<translation id="5317780077021120954">Opslaan</translation>
<translation id="536296301121032821">Opslaan van beleidsinstellingen is mislukt</translation>
-<translation id="5439770059721715174">Schemavalidatiefout op '<ph name="ERROR_PATH"/>': <ph name="ERROR"/></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="5439770059721715174">Schemavalidatiefout op '<ph name="ERROR_PATH" />': <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Onjuiste tijdstempel van beleid</translation>
<translation id="5470861586879999274">&amp;Opnieuw bewerken</translation>
<translation id="5509780412636533143">Beheerde bladwijzers</translation>
<translation id="5523118979700054094">Beleidsnaam</translation>
<translation id="552553974213252141">Is de tekst correct geëxtraheerd?</translation>
<translation id="5540224163453853">Kan het gevraagde artikel niet vinden.</translation>
+<translation id="5556459405103347317">Opnieuw laden</translation>
<translation id="5565735124758917034">Actief</translation>
<translation id="560412284261940334">Beheer wordt niet ondersteund</translation>
<translation id="5629630648637658800">Laden van beleidsinstellingen is mislukt</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Huidige gebruiker</translation>
<translation id="5813119285467412249">&amp;Opnieuw toevoegen</translation>
<translation id="5872918882028971132">Bovenliggende suggesties</translation>
-<translation id="587701087903783706">Weergave voor mobiele apparaten sluiten</translation>
<translation id="59107663811261420">Dit type kaart wordt voor deze verkoper niet ondersteund door Google Payments. Selecteer een andere kaart.</translation>
+<translation id="5975083100439434680">Uitzoomen</translation>
<translation id="5989320800837274978">Er worden geen vaste proxyservers en geen pac-script-URL gespecificeerd.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Sluiten</translation>
+<translation id="6060685159320643512">Pas op, dit zijn geen experimenten om zonder handschoenen aan te pakken</translation>
+<translation id="6151417162996330722">Het servercertificaat heeft een te lange geldigheidsperiode.</translation>
<translation id="6154808779448689242">Geretourneerde beleidstoken komt niet overeen met huidige token</translation>
<translation id="6165508094623778733">Meer informatie</translation>
<translation id="6259156558325130047">&amp;Opnieuw volgorde wijzigen</translation>
-<translation id="6263376278284652872">Bladwijzers voor <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Bladwijzers voor <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Postcode</translation>
<translation id="6337534724793800597">Beleid filteren op naam</translation>
+<translation id="6387478394221739770">Ben je geïnteresseerd in nieuwe, coole Chrome-functies? Probeer ons bèta-kanaal op chrome.com/beta.</translation>
+<translation id="6426993025560594914">Alle experimenten zijn beschikbaar op je platform.</translation>
<translation id="6445051938772793705">Land</translation>
<translation id="6458467102616083041">Genegeerd omdat de standaardzoekoptie door het beleid is uitgeschakeld.</translation>
<translation id="647261751007945333">Apparaatbeleid</translation>
<translation id="6512448926095770873">Deze pagina verlaten</translation>
<translation id="6529602333819889595">&amp;Opnieuw verwijderen</translation>
<translation id="6550675742724504774">Opties</translation>
-<translation id="6597614308054261376">Je probeert <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> te bereiken. Deze pagina kan momenteel niet via proxy worden overgedragen door Databesparing.</translation>
-<translation id="6628463337424475685">Zoeken via <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Je probeert <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> te bereiken. Deze pagina kan momenteel niet via proxy worden overgedragen door Databesparing.</translation>
+<translation id="6628463337424475685">Zoeken via <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Dit beleid is verouderd.</translation>
<translation id="6646897916597483132">Geef de viercijferige CVC-code op die op de voorkant van je kaart staat</translation>
+<translation id="674375294223700098">Onbekende fout met servercertificaat.</translation>
<translation id="6753269504797312559">Beleidswaarde</translation>
<translation id="6831043979455480757">Vertalen</translation>
<translation id="6839929833149231406">Gebied</translation>
<translation id="6874604403660855544">&amp;Opnieuw toevoegen</translation>
<translation id="6891596781022320156">Beleidsniveau wordt niet ondersteund.</translation>
<translation id="6915804003454593391">Gebruiker:</translation>
+<translation id="6957887021205513506">Het certificaat van de server lijkt vals te zijn.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">JavaScript-melding</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Je hebt geprobeerd <ph name="DOMAIN" /> te bereiken, maar de server heeft een certificaat gepresenteerd waarvan de geldigheidsperiode te lang is om betrouwbaar te zijn.</translation>
<translation id="7087282848513945231">County</translation>
-<translation id="7108649287766967076">De vertaling naar het <ph name="TARGET_LANGUAGE"/> is mislukt.</translation>
+<translation id="7108649287766967076">De vertaling naar het <ph name="TARGET_LANGUAGE" /> is mislukt.</translation>
<translation id="7139724024395191329">Emiraat</translation>
+<translation id="7179921470347911571">Nu opnieuw starten</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="7186367841673660872">Deze pagina is vertaald van het<ph name="ORIGINAL_LANGUAGE" />in het<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531"><ph name="SITE_NAME"/> doorzoeken op <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531"><ph name="SITE_NAME" /> doorzoeken op <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Er kan geen privéverbinding met <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tot stand worden gebracht, omdat de datum en tijd van de computer (<ph name="DATE_AND_TIME" />) onjuist zijn.</translation>
<translation id="7275334191706090484">Beheerde bladwijzers</translation>
<translation id="7298195798382681320">Aanbevolen</translation>
<translation id="7334320624316649418">&amp;Opnieuw volgorde wijzigen</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Verplicht</translation>
<translation id="7542995811387359312">Het automatisch invullen van creditcardnummers is uitgeschakeld, omdat dit formulier geen beveiligde verbinding gebruikt.</translation>
-<translation id="7568593326407688803">Deze pagina is geschreven in het<ph name="ORIGINAL_LANGUAGE"/>Wil je deze laten vertalen?</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="7568593326407688803">Deze pagina is geschreven in het<ph name="ORIGINAL_LANGUAGE" />Wil je deze laten vertalen?</translation>
<translation id="7569952961197462199">Creditcard verwijderen uit Chrome?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/> nooit vertalen</translation>
-<translation id="7610193165460212391">Waarde <ph name="VALUE"/> is buiten bereik.</translation>
+<translation id="7592362899630581445">Het certificaat van de server is in strijd met naambeperkingen.</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" /> nooit vertalen</translation>
+<translation id="7610193165460212391">Waarde <ph name="VALUE" /> is buiten bereik.</translation>
+<translation id="7674629440242451245">Ben je geïnteresseerd in nieuwe, coole Chrome-functies? Probeer ons ontwikkelaarskanaal op chrome.com/dev.</translation>
<translation id="7752995774971033316">Niet-beheerd</translation>
+<translation id="7761701407923456692">Het servercertificaat komt niet overeen met de URL.</translation>
<translation id="777702478322588152">Prefectuur</translation>
<translation id="7791543448312431591">Toevoegen</translation>
<translation id="7805768142964895445">Status</translation>
<translation id="7813600968533626083">Formuliersuggestie verwijderen uit Chrome?</translation>
<translation id="7887683347370398519">Controleer je CVC-code en probeer het opnieuw</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Het servercertificaat is nog niet geldig.</translation>
<translation id="7956713633345437162">Mobiele bladwijzers</translation>
<translation id="7961015016161918242">Nooit</translation>
<translation id="7977590112176369853">&lt;geef hier uw zoekopdracht op&gt;</translation>
-<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE"/> altijd vertalen in het <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE" /> altijd vertalen in het <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Desktopbladwijzers</translation>
<translation id="7995512525968007366">Niet opgegeven</translation>
-<translation id="8034522405403831421">Deze pagina is in het <ph name="SOURCE_LANGUAGE"/>. Vertalen naar het <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Overschrijving door bedrijf</translation>
+<translation id="8034522405403831421">Deze pagina is in het <ph name="SOURCE_LANGUAGE" />. Vertalen naar het <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Kan artikel niet bekijken.</translation>
<translation id="8091372947890762290">Activering is in behandeling op de server</translation>
<translation id="8194797478851900357">&amp;Verplaatsen ongedaan maken</translation>
-<translation id="8201077131113104583">Ongeldige update-URL voor de extensie met de ID '<ph name="EXTENSION_ID"/>'.</translation>
+<translation id="8201077131113104583">Ongeldige update-URL voor de extensie met de ID '<ph name="EXTENSION_ID" />'.</translation>
<translation id="8208216423136871611">Niet opslaan</translation>
<translation id="8218327578424803826">Toegewezen locatie:</translation>
<translation id="8249320324621329438">Laatst opgehaald:</translation>
+<translation id="8294431847097064396">Bron</translation>
<translation id="8308427013383895095">De vertaling is mislukt omdat er een probleem is opgetreden met de netwerkverbinding.</translation>
<translation id="8311778656528046050">Weet je zeker dat je deze pagina opnieuw wilt laden?</translation>
<translation id="8349305172487531364">Bladwijzerbalk</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Van toepassing op</translation>
<translation id="8530504477309582336">Dit type kaart wordt niet ondersteund door Google Payments. Selecteer een andere kaart.</translation>
<translation id="8553075262323480129">De vertaling is mislukt omdat de taal van de pagina niet kan worden bepaald.</translation>
-<translation id="8571890674111243710">Pagina wordt vertaald in het <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Er kan geen privéverbinding met <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tot stand worden gebracht, omdat de datum en tijd van je apparaat (<ph name="DATE_AND_TIME" />) onjuist zijn.</translation>
+<translation id="8571890674111243710">Pagina wordt vertaald in het <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Alle standaardinstellingen herstellen</translation>
<translation id="8713130696108419660">Onjuiste eerste handtekening</translation>
<translation id="8725066075913043281">Opnieuw proberen</translation>
+<translation id="8738058698779197622">Als je een veilige verbinding tot stand wilt brengen, moet je klok goed zijn ingesteld. Dit moet omdat de certificaten die deze websites gebruiken om zichzelf te identificeren, slechts gedurende bepaalde perioden geldig zijn. Aangezien de klok van je apparaat niet goed is ingesteld, kan Chromium deze certificaten niet verifiëren.</translation>
<translation id="8790007591277257123">&amp;Opnieuw verwijderen</translation>
<translation id="8804164990146287819">Privacybeleid</translation>
+<translation id="8820817407110198400">Bladwijzers</translation>
<translation id="8824019021993735287">Chrome kan je kaart momenteel niet verifiëren. Probeer het later opnieuw.</translation>
<translation id="8834246243508017242">Automatisch aanvullen inschakelen met contacten…</translation>
<translation id="883848425547221593">Andere bladwijzers</translation>
+<translation id="884923133447025588">Geen intrekkingsmechanisme gevonden.</translation>
<translation id="8866481888320382733">Fout bij het parseren van beleidsinstellingen</translation>
<translation id="8876793034577346603">Netwerkconfiguratie kan niet worden geparseerd.</translation>
<translation id="8891727572606052622">Ongeldige proxymodus.</translation>
-<translation id="8940229512486821554">Opdracht van <ph name="SEARCH_TERMS"/> uitvoeren: <ph name="EXTENSION_NAME"/></translation>
+<translation id="889901481107108152">Dit experiment is niet beschikbaar op je platform.</translation>
+<translation id="8903921497873541725">Inzoomen</translation>
+<translation id="8932102934695377596">Je klok loopt achter</translation>
+<translation id="8940229512486821554">Opdracht van <ph name="SEARCH_TERMS" /> uitvoeren: <ph name="EXTENSION_NAME" /></translation>
+<translation id="8971063699422889582">Het servercertificaat is verlopen.</translation>
<translation id="8988760548304185580">Geef de vervaldatum en driecijferige CVC-code op die op de achterkant van je kaart staan</translation>
-<translation id="9020542370529661692">Deze pagina is vertaald naar het <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Markeringen die op het hele systeem van toepassing zijn, kunnen alleen worden ingesteld door de eigenaar: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Deze pagina is vertaald naar het <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Je probeert <ph name="DOMAIN" /> te bereiken, maar de server heeft een ongeldig certificaat geretourneerd.</translation>
<translation id="9125941078353557812">Geef de driecijferige CVC-code op die op de achterkant van je kaart staat</translation>
<translation id="9137013805542155359">Origineel weergeven</translation>
<translation id="9148507642005240123">&amp;Bewerken ongedaan maken</translation>
<translation id="9154176715500758432">Op deze pagina blijven</translation>
<translation id="9170848237812810038">&amp;Ongedaan maken</translation>
+<translation id="917450738466192189">Het servercertificaat is ongeldig.</translation>
+<translation id="9187827965378254003">Het lijkt erop dat er momenteel geen experimenten beschikbaar zijn.</translation>
<translation id="9207861905230894330">Kan artikel niet toevoegen.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">FORMULIER LEEGMAKEN</translation>
+<translation id="988159990683914416">Ontwikkelaarsbuild</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_no.xtb b/chromium/components/strings/components_strings_no.xtb
index 4dbe488a79d..0a5457e4249 100644
--- a/chromium/components/strings/components_strings_no.xtb
+++ b/chromium/components/strings/components_strings_no.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="no">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="no">
+<translation id="1032854598605920125">Rotér med klokken</translation>
<translation id="1055184225775184556">&amp;Angre tilleggingen</translation>
<translation id="106701514854093668">Bokmerker på datamaskinen</translation>
-<translation id="1103523840287552314">Oversett alltid <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Tilpass til vindusbredden</translation>
+<translation id="1103523840287552314">Oversett alltid <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Angre omorganiseringen</translation>
<translation id="111844081046043029">Er du sikker på at du vil forlate denne siden?</translation>
<translation id="112840717907525620">Bufferen for enhetsinnstillinger er OK</translation>
<translation id="1132774398110320017">Innstillinger for autofyll i Chrome</translation>
-<translation id="1152921474424827756">Åpne en <ph name="BEGIN_LINK"/>bufret kopi<ph name="END_LINK"/> av <ph name="URL"/></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="1152921474424827756">Åpne en <ph name="BEGIN_LINK" />bufret kopi<ph name="END_LINK" /> av <ph name="URL" /></translation>
+<translation id="121201262018556460">Du forsøkte å gå til <ph name="DOMAIN" />, men tjeneren presenterte et sertifikat som inneholder en svak nøkkel. En angriper kan ha løst den private nøkkelen, og tjeneren er kanskje ikke den tjeneren du forventet (det kan hende at du kommuniserer med en angriper).</translation>
<translation id="1227224963052638717">Ukjent innstilling.</translation>
<translation id="1227633850867390598">Skjul verdien</translation>
<translation id="1228893227497259893">Feil enhetsidentifikator</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Registreringsdomene:</translation>
<translation id="1344588688991793829">Innstillinger for autofyll i Chromium</translation>
<translation id="1426410128494586442">Ja</translation>
+<translation id="1430915738399379752">Skriv ut</translation>
<translation id="1455235771979731432">Det oppsto et problem under forsøket på å bekrefte kortet ditt. Kontrollér Internett-tilkoblingen din, og prøv igjen.</translation>
<translation id="1491151370853475546">Last inn denne siden på nytt</translation>
<translation id="1549470594296187301">Denne funksjonen kan ikke brukes når JavaScript er slått av.</translation>
-<translation id="1639239467298939599">Laster inn</translation>
<translation id="1640180200866533862">Brukerretningslinjer</translation>
<translation id="1644184664548287040">Nettverkskonfigurasjonen er ugyldig og kan ikke importeres.</translation>
-<translation id="1693754753824026215">Varsel fra <ph name="SITE"/>:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet utløp i går. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen mellom deg og nettstedet. Klokken på datamaskinen din er stilt til <ph name="CURRENT_DATE" />. Er det riktig? Hvis ikke bør du stille klokken på systemet og laste inn denne siden på nytt.}other{Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet utløp for # dager siden. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen mellom deg og nettstedet. Klokken på datamaskinen din er stilt til <ph name="CURRENT_DATE" />. Er det riktig? Hvis ikke bør du stille klokken på systemet og laste inn denne siden på nytt.}}</translation>
+<translation id="168841957122794586">Tjenersertifikatet inneholder en svak kryptografisk nøkkel.</translation>
+<translation id="1693754753824026215">Varsel fra <ph name="SITE" />:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Sikkerhetssertifikatet til tjeneren er ikke klarert av enhetens operativsystem. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
<translation id="1821930232296380041">Ugyldig forespørsel eller forespørselsparametere</translation>
-<translation id="1853748787962613237">Kunne ikke vise artikkelen.</translation>
<translation id="1871208020102129563">Mellomtjeneren er angitt til å bruke statiske proxytjenere, ikke en nettadresse med .pac-skript.</translation>
-<translation id="1875753206475436906">heuristic type: <ph name="HEURISTIC_TYPE"/>
- server type: <ph name="SERVER_TYPE"/>
- field signature: <ph name="FIELD_SIGNATURE"/>
- form signature: <ph name="FORM_SIGNATURE"/>
- experiment id: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Gå til <ph name="LINK"/></translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/>-bokmerker</translation>
+<translation id="194030505837763158">Gå til <ph name="LINK" /></translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" />-bokmerker</translation>
<translation id="1973335181906896915">Serialiseringsfeil</translation>
+<translation id="1974060860693918893">Avansert</translation>
<translation id="2025186561304664664">Mellomtjeneren er innstilt på automatisk konfigurasjon.</translation>
<translation id="2025623846716345241">Bekreft ny innlasting</translation>
-<translation id="2030481566774242610">Mener du <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Mener du <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Postnummer</translation>
<translation id="20817612488360358">Innstillinger for systemmellomtjener er stilt inn på å brukes, men en uttrykkelig mellomtjenerkonfigurasjon er også angitt.</translation>
<translation id="2094505752054353250">Domenene samsvarer ikke</translation>
<translation id="2096368010154057602">Avdeling</translation>
<translation id="2113977810652731515">Kort</translation>
-<translation id="2114841414352855701">Ignorert fordi det ble overstyrt av <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Ignorert fordi det ble overstyrt av <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Bokmerker for mobil</translation>
+<translation id="2171101176734966184">Du forsøkte å gå til <ph name="DOMAIN" />, men tjeneren presenterte et sertifikat som er signert med en usikker signaturalgoritme. Dette betyr at sikkerhetslegitimasjonen tjeneren har presentert kan være forfalsket. Tjeneren kan med andre ord være enn annen tjener enn du tror (det vil si at du kanskje kommuniserer med en angriper).</translation>
<translation id="2181821976797666341">Retningslinjer</translation>
<translation id="2212735316055980242">Innstillingene ble ikke funnet</translation>
<translation id="2213606439339815911">Henter oppføringer …</translation>
<translation id="225207911366869382">Denne verdien er foreldet for denne innstillingen.</translation>
<translation id="2262243747453050782">HTTP-feil</translation>
-<translation id="2270192940992995399">Kunne ikke finne artikkelen.</translation>
-<translation id="2328300916057834155">Ignorerte ugyldig bokmerke ved indeks <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Utilgjengelige eksperimenter</translation>
+<translation id="229702904922032456">Et rotsertifikat eller mellomliggende sertifikat er utløpt.</translation>
+<translation id="2328300916057834155">Ignorerte ugyldig bokmerke ved indeks <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Andre bokmerker</translation>
<translation id="2359808026110333948">Fortsett</translation>
<translation id="2367567093518048410">Nivå</translation>
+<translation id="2384307209577226199">Bedriftsstandard</translation>
+<translation id="2386255080630008482">Tjenerens sertifikat er tilbakekalt.</translation>
<translation id="2392959068659972793">Vis innstillinger uten verdi</translation>
<translation id="2396249848217231973">&amp;Angre slettingen</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="2455981314101692989">Denne nettsiden har deaktivert automatisk utfylling for dette skjemaet.</translation>
<translation id="2479410451996844060">Ugyldig nettadresse for søk.</translation>
+<translation id="2491120439723279231">Tjenerens sertifikat inneholder feil.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2498091847651709837">Skann nytt kort</translation>
<translation id="2556876185419854533">&amp;Angre endringen</translation>
-<translation id="2581221116934462656">Vil du at <ph name="PRODUCT_NAME"/> skal tilby å oversette sider på <ph name="LANGUAGE_NAME"/> fra dette nettstedet neste gang?</translation>
+<translation id="2581221116934462656">Vil du at <ph name="PRODUCT_NAME" /> skal tilby å oversette sider på <ph name="LANGUAGE_NAME" /> fra dette nettstedet neste gang?</translation>
<translation id="2587841377698384444">ID for katalog-API:</translation>
<translation id="2597378329261239068">Dette dokumentet er passordbeskyttet. Skriv inn et passord.</translation>
+<translation id="2625385379895617796">Klokken går for fort</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2653659639078652383">Send</translation>
<translation id="2704283930420550640">Verdien samsvarer ikke med formatet.</translation>
<translation id="2721148159707890343">Forespørselen var vellykket</translation>
+<translation id="2728127805433021124">Tjenerens sertifikat er signert med en usikker signaturalgoritme.</translation>
<translation id="2774256287122201187">Du kan fortsette. Hvis du fortsetter til siden, vises ikke denne advarselen igjen før det har gått fem minutter.</translation>
<translation id="277499241957683684">Manglende enhetsoppføring</translation>
<translation id="2835170189407361413">Slett skjemaet</translation>
-<translation id="2855922900409897335">Bekreft følgende kort: <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Bekreft følgende kort: <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Tjenerens sikkerhetssertifikat er utløpt. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din. Datamaskinens klokke er for øyeblikket satt til <ph name="CURRENT_TIME" />. Ser det riktig ut? Hvis det ikke gjør det, bør du korrigere systemets klokke og deretter laste inn denne siden på nytt.</translation>
+<translation id="2922350208395188000">Tjenerens sertifikat kan ikke kontrolleres.</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="2958431318199492670">Nettverkskonfigurasjonen overholder ikke ONC-standarden. Deler av konfigurasjonen kan muligens ikke importeres.</translation>
<translation id="2972581237482394796">Gjø&amp;r om</translation>
-<translation id="3010559122411665027">Listeoppføring «<ph name="ENTRY_INDEX"/>»: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Listeoppføring «<ph name="ENTRY_INDEX" />»: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Feil type enhetsinnstillinger</translation>
<translation id="3105172416063519923">Ressurs-ID:</translation>
<translation id="3145945101586104090">Kunne ikke avkode responsen</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Øy</translation>
<translation id="3219579145727097045">Skriv inn utløpsdatoen og den firesifrede CVC-koden du finner på forsiden av kortet ditt.</translation>
-<translation id="3228969707346345236">Oversettelsen mislyktes fordi siden allerede er på <ph name="LANGUAGE"/>.</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="3228969707346345236">Oversettelsen mislyktes fordi siden allerede er på <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Angre omorganiseringen</translation>
+<translation id="3286538390144397061">Start på nytt nå</translation>
<translation id="333371639341676808">Hindre denne siden i å opprette flere dialogbokser.</translation>
-<translation id="3369366829301677151">Oppdater og bekreft følgende kort: <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">innstillinger</translation>
+<translation id="3369192424181595722">Klokkefeil</translation>
+<translation id="3369366829301677151">Oppdater og bekreft følgende kort: <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Godkjenningen er opphevet</translation>
<translation id="3377188786107721145">Feil under analysen av enhetsinnstillinger</translation>
<translation id="3380365263193509176">Ukjent feil</translation>
<translation id="3380864720620200369">Klient-ID:</translation>
<translation id="3427342743765426898">&amp;Endre likevel</translation>
+<translation id="3435896845095436175">Slå på</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Hentingsintervall:</translation>
+<translation id="3462200631372590220">Skjul detaljer</translation>
+<translation id="3528171143076753409">Tjenerens sertifikat er ikke pålitelig.</translation>
<translation id="3542684924769048008">Bruk passord for:</translation>
<translation id="3583757800736429874">&amp;Flytt likevel</translation>
<translation id="3623476034248543066">Vis verdien</translation>
+<translation id="3648607100222897006">Disse eksperimentelle funksjonene kan bli endret, satt på pause eller forsvinne når som helst. Vi gir absolutt ingen garantier om hva som kan skje hvis du slår på et av disse eksperimentene – nettleseren kan til og med spontanantenne. Spøk til side: Nettleseren kan komme til å slette alle dataene dine eller sikkerheten og personvernet kan bli kompromittert på uventede måter. Eventuelle eksperimenter du aktiverer bli aktivert for alle brukere av denne nettleseren. Vær forsiktig hvis du fortsetter.</translation>
<translation id="3650584904733503804">Valideringen var vellykket</translation>
<translation id="370665806235115550">Laster inn...</translation>
<translation id="3712624925041724820">Lisensene er oppbrukt</translation>
<translation id="3739623965217189342">En link du kopierte</translation>
<translation id="375403751935624634">Oversettelsen mislyktes på grunn av en tjenerfeil.</translation>
<translation id="385051799172605136">Tilbake</translation>
+<translation id="3858027520442213535">Oppdater dato og klokkeslett</translation>
<translation id="3884278016824448484">Motstridende enhetsidentifikator</translation>
<translation id="3885155851504623709">Kommune</translation>
<translation id="3934680773876859118">Kan ikke laste inn PDF-dokument</translation>
<translation id="3963721102035795474">Lesermodus</translation>
<translation id="4030383055268325496">&amp;Angre tilleggingen</translation>
-<translation id="4058922952496707368">Nøkkel – «<ph name="SUBKEY"/>»: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ADVARSEL</translation>
+<translation id="4058922952496707368">Nøkkel – «<ph name="SUBKEY" />»: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Konfigurasjonen av proxytjeneren er angitt til å bruke en nettadresse med .pac-skript, ikke statiske proxytjenere.</translation>
<translation id="409504436206021213">Ikke last inn på nytt</translation>
<translation id="4103249731201008433">Enhetens serienummer er ugyldig</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Dårlig signatur</translation>
<translation id="4269787794583293679">(Uten brukernavn)</translation>
<translation id="4300246636397505754">Overordnede forslag</translation>
-<translation id="4372948949327679948">Forventet <ph name="VALUE_TYPE"/>-verdi.</translation>
+<translation id="4325863107915753736">Artikkelen ble ikke funnet</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="4394049700291259645">Slå av</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="443673843213245140">Bruk av mellomtjener er deaktivert, men det er angitt en uttrykkelig mellomtjenerkonfigurasjon.</translation>
-<translation id="4506176782989081258">Valideringsfeil: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Valideringsfeil: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Vil du fjerne adressen fra Chrome?</translation>
<translation id="4594403342090139922">&amp;Angre slettingen</translation>
<translation id="4607653538520819196">Denne siden kan ikke sendes gjennom Datasparing.</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="4726672564094551039">Last inn retningslinjer på nytt</translation>
+<translation id="4728558894243024398">Plattform</translation>
+<translation id="4771973620359291008">Det har oppstått en ukjent feil.</translation>
<translation id="4800132727771399293">Kontrollér utløpsdatoen og CVC-koden, og prøv igjen.</translation>
<translation id="4813512666221746211">Nettverksfeil</translation>
+<translation id="4816492930507672669">Tilpass til siden</translation>
<translation id="4850886885716139402">Visning</translation>
-<translation id="4923417429809017348">Denne siden er oversatt til <ph name="LANGUAGE_LANGUAGE"/> fra et ukjent språk</translation>
+<translation id="4923417429809017348">Denne siden er oversatt til <ph name="LANGUAGE_LANGUAGE" /> fra et ukjent språk</translation>
<translation id="4926049483395192435">Må angis.</translation>
<translation id="4968547170521245791">Kan ikke sende gjennom proxy-tjeneren</translation>
-<translation id="498957508165411911">Vil du oversette fra <ph name="ORIGINAL_LANGUAGE"/> til <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Vil du oversette fra <ph name="ORIGINAL_LANGUAGE" /> til <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Ugyldig funksjonalitet for sikkerhetskopiering</translation>
<translation id="5031870354684148875">Om Google Oversett</translation>
+<translation id="5045550434625856497">Feil passord</translation>
+<translation id="5087286274860437796">Sertifikatet til tjeneren er ikke gyldig for øyeblikket.</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="5145883236150621069">Feilkode i responsen for enhetsinnstillinger</translation>
<translation id="5172758083709347301">Datamaskin</translation>
-<translation id="5179510805599951267">Er ikke dette <ph name="ORIGINAL_LANGUAGE"/>? Rapportér denne feilen</translation>
+<translation id="5179510805599951267">Er ikke dette <ph name="ORIGINAL_LANGUAGE" />? Rapportér denne feilen</translation>
<translation id="5190835502935405962">Bokmerkerad</translation>
+<translation id="5199729219167945352">Eksperimenter</translation>
+<translation id="5251803541071282808">Nettsky</translation>
<translation id="5295309862264981122">Bekreft navigering</translation>
<translation id="5299298092464848405">Feil under analysen av enhetsinnstillingene</translation>
+<translation id="5316812925700871227">Rotér mot klokken</translation>
<translation id="5317780077021120954">Lagre</translation>
<translation id="536296301121032821">Kunne ikke lagre angivelsen for enhetsinnstillinger</translation>
-<translation id="5439770059721715174">Skjemavalideringsfeil i «<ph name="ERROR_PATH"/>»: <ph name="ERROR"/></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="5439770059721715174">Skjemavalideringsfeil i «<ph name="ERROR_PATH" />»: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Feil tidsstempel for enhetsinnstillinger</translation>
<translation id="5470861586879999274">&amp;Endre likevel</translation>
<translation id="5509780412636533143">Administrerte bokmerker</translation>
<translation id="5523118979700054094">Navn på retningslinje</translation>
<translation id="552553974213252141">Ble tekstutdraget riktig?</translation>
<translation id="5540224163453853">Den forespurte artikkelen ble ikke funnet.</translation>
+<translation id="5556459405103347317">Last inn på nytt</translation>
<translation id="5565735124758917034">Aktiv</translation>
<translation id="560412284261940334">Administrering støttes ikke</translation>
<translation id="5629630648637658800">Kunne ikke laste in angivelsen for enhetsinnstillinger</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Gjeldende bruker</translation>
<translation id="5813119285467412249">&amp;Legg til likevel</translation>
<translation id="5872918882028971132">Overordnede forslag</translation>
-<translation id="587701087903783706">Avslutt mobilvennlig visning</translation>
<translation id="59107663811261420">Denne korttypen støttes ikke av Google Payments for denne selgeren. Velg et annet kort.</translation>
+<translation id="5975083100439434680">Zoom ut</translation>
<translation id="5989320800837274978">Verken statiske proxytjenere eller en nettadresse med .pac-skript er angitt.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Lukk</translation>
+<translation id="6060685159320643512">Vær forsiktig. Disse eksperimentene kan bite</translation>
+<translation id="6151417162996330722">Tjenersertifikatet har en gyldighetsperiode som er for lang.</translation>
<translation id="6154808779448689242">Det returnerte tokenet for enhetsinnstillinger samsvarer ikke med det gjeldende tokenet</translation>
<translation id="6165508094623778733">Les mer</translation>
<translation id="6259156558325130047">&amp;Omorganiser likevel</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/>-bokmerker</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" />-bokmerker</translation>
<translation id="6282194474023008486">Postnummer</translation>
<translation id="6337534724793800597">Filtrér retningslinjer etter navn</translation>
+<translation id="6387478394221739770">Interessert i nye kule Chrome-funksjoner? Prøv betakanalen vår på chrome.com/beta</translation>
+<translation id="6426993025560594914">Alle eksperimenter er tilgjengelige på plattformen din!</translation>
<translation id="6445051938772793705">Land</translation>
<translation id="6458467102616083041">Ignorert fordi standardsøk er deaktivert i henhold til retningslinje.</translation>
<translation id="647261751007945333">Enhetsinnstillinger</translation>
<translation id="6512448926095770873">Forlat siden</translation>
<translation id="6529602333819889595">&amp;Slett likevel</translation>
<translation id="6550675742724504774">Alternativer</translation>
-<translation id="6597614308054261376">Du prøver å nå <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Denne siden kan ikke sendes gjennom Datasparing akkurat nå.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Søk</translation>
+<translation id="6597614308054261376">Du prøver å nå <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Denne siden kan ikke sendes gjennom Datasparing akkurat nå.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Søk</translation>
<translation id="6644283850729428850">Denne retningslinjen er foreldet.</translation>
<translation id="6646897916597483132">Skriv inn den firesifrede CVC-koden du finner på forsiden av kortet ditt.</translation>
+<translation id="674375294223700098">Ukjent feil med tjenersertifikat.</translation>
<translation id="6753269504797312559">Retningslinjeverdi</translation>
<translation id="6831043979455480757">Oversett</translation>
<translation id="6839929833149231406">Område</translation>
<translation id="6874604403660855544">&amp;Legg til likevel</translation>
<translation id="6891596781022320156">Innstillingsnivået støttes ikke.</translation>
<translation id="6915804003454593391">Bruker:</translation>
+<translation id="6957887021205513506">Tjenersertifikatet ser ut til å være forfalsket.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">JavaScript-varsel</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Du prøvde å nå <ph name="DOMAIN" />. Tjeneren presenterte et sertifikat som har en gyldighetsperiode som er for lang til å være pålitelig.</translation>
<translation id="7087282848513945231">Fylke</translation>
-<translation id="7108649287766967076">Oversettelsen til <ph name="TARGET_LANGUAGE"/> mislyktes.</translation>
+<translation id="7108649287766967076">Oversettelsen til <ph name="TARGET_LANGUAGE" /> mislyktes.</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7179921470347911571">Start på nytt nå</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="7186367841673660872">Denne siden har blitt oversatt fra<ph name="ORIGINAL_LANGUAGE" />til<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Søk på <ph name="SITE_NAME"/> etter <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Søk på <ph name="SITE_NAME" /> etter <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">En privat forbindelse til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> kan ikke opprettes fordi datoen og klokkeslettet (<ph name="DATE_AND_TIME" />) på datamaskinen er feil.</translation>
<translation id="7275334191706090484">Administrerte bokmerker</translation>
<translation id="7298195798382681320">Anbefalt</translation>
<translation id="7334320624316649418">&amp;Omorganiser likevel</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obligatorisk</translation>
<translation id="7542995811387359312">Automatisk utfylling av kredittkort er deaktivert fordi dette skjemaet ikke bruker en sikker tilkobling.</translation>
-<translation id="7568593326407688803">Denne siden er på<ph name="ORIGINAL_LANGUAGE"/>Vil du ha den oversatt?</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="7568593326407688803">Denne siden er på<ph name="ORIGINAL_LANGUAGE" />Vil du ha den oversatt?</translation>
<translation id="7569952961197462199">Vil du fjerne kredittkortet fra Chrome?</translation>
-<translation id="7600965453749440009">Oversett aldri <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Verdien er utenfor rekkevidden <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Tjenerens sertifikat bryter navnereglene.</translation>
+<translation id="7600965453749440009">Oversett aldri <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Verdien er utenfor rekkevidden <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Interessert i nye kule Chrome-funksjoner? Prøv utviklerkanalen vår på chrome.com/dev</translation>
<translation id="7752995774971033316">Administreres ikke</translation>
+<translation id="7761701407923456692">Tjenerens sertifikat samsvarer ikke med nettadressen.</translation>
<translation id="777702478322588152">Prefektur</translation>
<translation id="7791543448312431591">Legg til</translation>
<translation id="7805768142964895445">Status</translation>
<translation id="7813600968533626083">Vil du fjerne skjemaforslaget fra Chrome?</translation>
<translation id="7887683347370398519">Kontrollér CVC-koden din, og prøv igjen.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Tjenerens sertifikat er ikke gyldig ennå.</translation>
<translation id="7956713633345437162">Bokmerker for mobil</translation>
<translation id="7961015016161918242">Aldri</translation>
<translation id="7977590112176369853">&lt;skriv inn søk&gt;</translation>
-<translation id="7983301409776629893">Oversett alltid <ph name="ORIGINAL_LANGUAGE"/> til <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Oversett alltid <ph name="ORIGINAL_LANGUAGE" /> til <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Bokmerker på datamaskinen</translation>
<translation id="7995512525968007366">Ikke spesifisert</translation>
-<translation id="8034522405403831421">Denne siden er på <ph name="SOURCE_LANGUAGE"/>. Vil du oversette den til <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Bedriftsoverstyring</translation>
+<translation id="8034522405403831421">Denne siden er på <ph name="SOURCE_LANGUAGE" />. Vil du oversette den til <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Kunne ikke åpne artikkelen.</translation>
<translation id="8091372947890762290">Aktivering venter på tjeneren</translation>
<translation id="8194797478851900357">&amp;Angre flyttingen</translation>
-<translation id="8201077131113104583">Ugyldig oppdaterings-URL for utvidelse med ID «<ph name="EXTENSION_ID"/>».</translation>
+<translation id="8201077131113104583">Ugyldig oppdaterings-URL for utvidelse med ID «<ph name="EXTENSION_ID" />».</translation>
<translation id="8208216423136871611">Ikke lagre</translation>
<translation id="8218327578424803826">Tilordnet posisjon:</translation>
<translation id="8249320324621329438">Sist hentet:</translation>
+<translation id="8294431847097064396">Kilde</translation>
<translation id="8308427013383895095">Oversettelsen mislyktes på grunn av et problem med nettverksforbindelsen.</translation>
<translation id="8311778656528046050">Er du sikker på at du vil laste inn denne siden på nytt?</translation>
<translation id="8349305172487531364">Bokmerkerad</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Gjelder for</translation>
<translation id="8530504477309582336">Denne korttypen støttes ikke av Google Payments. Velg et annet kort.</translation>
<translation id="8553075262323480129">Oversettelsen mislyktes fordi sidens språk ikke kunne fastslås.</translation>
-<translation id="8571890674111243710">Oversett siden til <ph name="LANGUAGE"/></translation>
+<translation id="8559762987265718583">En privat tilkobling til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> kunne ikke etableres fordi datoen og klokkeslettet (<ph name="DATE_AND_TIME" />) er feil på enheten.</translation>
+<translation id="8571890674111243710">Oversett siden til <ph name="LANGUAGE" /></translation>
+<translation id="8647750283161643317">Tilbakestill alle til standard</translation>
<translation id="8713130696108419660">Feil innledende signatur</translation>
<translation id="8725066075913043281">Prøv igjen</translation>
+<translation id="8738058698779197622">Klokken din må være riktig stilt for at du skal kunne opprette en sikker forbindelse. Sertifikatene som nettsteder bruker til å identifisere seg med, er nemlig bare gyldige i en viss tid. Siden enhetens klokke er feil, kan ikke Chromium kontrollere disse sertifikatene.</translation>
<translation id="8790007591277257123">&amp;Slett likevel</translation>
<translation id="8804164990146287819">Personvernregler</translation>
+<translation id="8820817407110198400">Bokmerker</translation>
<translation id="8824019021993735287">Chrome kunne ikke bekrefte kortet ditt akkurat nå. Prøv igjen senere.</translation>
<translation id="8834246243508017242">Aktiver autofyll for Kontakter</translation>
<translation id="883848425547221593">Andre bokmerker</translation>
+<translation id="884923133447025588">Finner ingen tilbakekallingsmekanisme.</translation>
<translation id="8866481888320382733">Analysefeil i angivelsen av enhetrsinnstillinger</translation>
<translation id="8876793034577346603">Nettverkskonfigurasjon kunne ikke analyseres.</translation>
<translation id="8891727572606052622">Ugyldig modus for mellomtjener.</translation>
-<translation id="8940229512486821554">Kjør <ph name="EXTENSION_NAME"/>-kommando: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Beklager, dette eksperimentet er ikke er tilgjengelig på plattformen din.</translation>
+<translation id="8903921497873541725">Zoom inn</translation>
+<translation id="8932102934695377596">Klokken går for sent</translation>
+<translation id="8940229512486821554">Kjør <ph name="EXTENSION_NAME" />-kommando: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Tjenerens sertifikat er utløpt.</translation>
<translation id="8988760548304185580">Skriv inn utløpsdatoen og den tresifrede CVC-koden du finner på baksiden av kortet ditt.</translation>
-<translation id="9020542370529661692">Denne siden har blitt oversatt til <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Rapporteringer som gjelder for hele systemet kan bare angis av eieren: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Denne siden har blitt oversatt til <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Du forsøkte å nå <ph name="DOMAIN" />, men tjeneren oppga et ugyldig sertifikat.</translation>
<translation id="9125941078353557812">Skriv inn den tresifrede CVC-koden du finner på baksiden av kortet ditt.</translation>
<translation id="9137013805542155359">Vis original</translation>
<translation id="9148507642005240123">&amp;Angre endringen</translation>
<translation id="9154176715500758432">Bli værende på denne siden</translation>
<translation id="9170848237812810038">&amp;Angre</translation>
+<translation id="917450738466192189">Tjenerens sertifikat er ugyldig.</translation>
+<translation id="9187827965378254003">Det er dessverre ingen eksperimenter tilgjengelig for øyeblikket.</translation>
<translation id="9207861905230894330">Kunne ikke legge til artikkelen.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">SLETT INNHOLDET I SKJEMAET</translation>
+<translation id="988159990683914416">Utviklerversjon</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_pl.xtb b/chromium/components/strings/components_strings_pl.xtb
index 8f2ac73bf85..79b227e90f2 100644
--- a/chromium/components/strings/components_strings_pl.xtb
+++ b/chromium/components/strings/components_strings_pl.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="pl">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pl">
+<translation id="1032854598605920125">Obróć w prawo</translation>
<translation id="1055184225775184556">&amp;Cofnij dodanie</translation>
<translation id="106701514854093668">Zakładki na komputerze</translation>
-<translation id="1103523840287552314">Zawsze tłumacz z języka: <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Dopasuj do szerokości</translation>
+<translation id="1103523840287552314">Zawsze tłumacz z języka: <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Cofnij zmianę kolejności</translation>
<translation id="111844081046043029">Czy na pewno chcesz opuścić tę stronę?</translation>
<translation id="112840717907525620">Pamięć podręczna zasad: OK</translation>
<translation id="1132774398110320017">Ustawienia autouzupełniania Chrome...</translation>
-<translation id="1152921474424827756">Przejdź do <ph name="BEGIN_LINK"/>kopii<ph name="END_LINK"/> <ph name="URL"/> w pamięci podręcznej</translation>
+<translation id="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="1152921474424827756">Przejdź do <ph name="BEGIN_LINK" />kopii<ph name="END_LINK" /> <ph name="URL" /> w pamięci podręcznej</translation>
+<translation id="121201262018556460">Próbujesz wejść na <ph name="DOMAIN" />, ale serwer przedstawił certyfikat ze słabym kluczem. Intruz mógł uzyskać klucz prywatny, a serwer może nie być tym, którego oczekujesz (możliwe, że komunikujesz się z intruzem).</translation>
<translation id="1227224963052638717">Nieznana zasada.</translation>
<translation id="1227633850867390598">Ukryj wartość</translation>
<translation id="1228893227497259893">Błędny identyfikator elementu</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Domena rejestracji:</translation>
<translation id="1344588688991793829">Ustawienia autouzupełniania Chromium...</translation>
<translation id="1426410128494586442">Tak</translation>
+<translation id="1430915738399379752">Drukuj</translation>
<translation id="1455235771979731432">Podczas weryfikacji karty wystąpił problem. Sprawdź połączenie internetowe i spróbuj ponownie.</translation>
<translation id="1491151370853475546">Załaduj tę stronę ponownie</translation>
<translation id="1549470594296187301">Aby można było korzystać z tej funkcji, musi być włączony JavaScript.</translation>
-<translation id="1639239467298939599">Wczytywanie</translation>
<translation id="1640180200866533862">Zasady dotyczące użytkowników</translation>
<translation id="1644184664548287040">Konfiguracja sieci jest nieprawidłowa i nie można jej zaimportować.</translation>
-<translation id="1693754753824026215">Komunikat ze strony <ph name="SITE"/>:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł wczoraj. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę.}few{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł # dni temu. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę.}many{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł # dni temu. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę.}other{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł # dnia temu. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę.}}</translation>
+<translation id="168841957122794586">Certyfikat serwera ma słaby klucz kryptograficzny.</translation>
+<translation id="1693754753824026215">Komunikat ze strony <ph name="SITE" />:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa nie jest zaufany w systemie operacyjnym tego urządzenia. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
<translation id="1821930232296380041">Nieprawidłowe żądanie lub jego parametry</translation>
-<translation id="1853748787962613237">Nie udało się wyświetlić artykułu.</translation>
<translation id="1871208020102129563">Proxy skonfigurowano do używania stałych serwerów proxy, a nie URL-a skryptu PAC.</translation>
-<translation id="1875753206475436906">typ heurystyczny: <ph name="HEURISTIC_TYPE"/>
- typ serwera: <ph name="SERVER_TYPE"/>
- podpis pola: <ph name="FIELD_SIGNATURE"/>
- podpis formularza: <ph name="FORM_SIGNATURE"/>
- identyfikator eksperymentu: „<ph name="EXPERIMENT_ID"/>”</translation>
-<translation id="194030505837763158">Wejdź na <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Zakładki z <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Wejdź na <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Zakładki z <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Podczas przekształcania do postaci szeregowej wystąpił błąd</translation>
+<translation id="1974060860693918893">Zaawansowane</translation>
<translation id="2025186561304664664">Ustawiono automatyczne konfigurowanie proxy.</translation>
<translation id="2025623846716345241">Potwierdź ponowne ładowanie</translation>
-<translation id="2030481566774242610">Czy chodziło Ci o <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Czy chodziło Ci o <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Kod pocztowy</translation>
<translation id="20817612488360358">Skonfigurowano używanie systemowych ustawień proxy, ale podano też jawną konfigurację proxy.</translation>
<translation id="2094505752054353250">Niewłaściwa domena</translation>
<translation id="2096368010154057602">Departament</translation>
<translation id="2113977810652731515">Karta</translation>
-<translation id="2114841414352855701">Ignorowana, ponieważ jest zastąpiona przez <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Ignorowana, ponieważ jest zastąpiona przez <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Klient natywny</translation>
<translation id="213826338245044447">Zakładki na komórce</translation>
+<translation id="2171101176734966184">Próbujesz wejść na <ph name="DOMAIN" />, ale serwer przedstawił certyfikat podpisany słabym algorytmem. Oznacza to, że dane uwierzytelniające podane przez serwer mogły zostać sfałszowane, a serwer może nie być tym, którego oczekujesz (możliwe, że komunikujesz się z intruzem).</translation>
<translation id="2181821976797666341">Zasady</translation>
<translation id="2212735316055980242">Nie znaleziono zasady</translation>
<translation id="2213606439339815911">Pobieram wpisy...</translation>
<translation id="225207911366869382">Ta wartość tej zasady została wycofana.</translation>
<translation id="2262243747453050782">Błąd HTTP</translation>
-<translation id="2270192940992995399">Nie udało się znaleźć artykułu.</translation>
-<translation id="2328300916057834155">Zignorowano nieprawidłową zakładkę w indeksie <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Niedostępne eksperymenty</translation>
+<translation id="229702904922032456">Wygasł certyfikat główny lub pośredniczący.</translation>
+<translation id="2328300916057834155">Zignorowano nieprawidłową zakładkę w indeksie <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Inne zakładki</translation>
<translation id="2359808026110333948">Kontynuuj</translation>
<translation id="2367567093518048410">Poziom</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="2396249848217231973">&amp;Cofnij usunięcie</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="2455981314101692989">Automatyczne wypełnianie tego formularza zostało wyłączone przez stronę internetową.</translation>
<translation id="2479410451996844060">Nieprawidłowy URL wyszukiwania</translation>
+<translation id="2491120439723279231">Certyfikat serwera zawiera błędy.</translation>
<translation id="2495083838625180221">Parser JSON</translation>
<translation id="2498091847651709837">Zeskanuj nową kartę</translation>
<translation id="2556876185419854533">&amp;Cofnij edycję</translation>
-<translation id="2581221116934462656">Czy następnym razem <ph name="PRODUCT_NAME"/> ma zaproponować Ci tłumaczenie stron tej witryny, których język to <ph name="LANGUAGE_NAME"/>?</translation>
+<translation id="2581221116934462656">Czy następnym razem <ph name="PRODUCT_NAME" /> ma zaproponować Ci tłumaczenie stron tej witryny, których język to <ph name="LANGUAGE_NAME" />?</translation>
<translation id="2587841377698384444">Identyfikator interfejsu API katalogu:</translation>
<translation id="2597378329261239068">Ten dokument jest chroniony hasłem. Wprowadź hasło.</translation>
+<translation id="2625385379895617796">Twój zegar się śpieszy</translation>
<translation id="2639739919103226564">Stan:</translation>
+<translation id="2653659639078652383">Prześlij</translation>
<translation id="2704283930420550640">Wartość nie pasuje do formatu.</translation>
<translation id="2721148159707890343">Żądanie wykonane pomyślnie</translation>
+<translation id="2728127805433021124">Certyfikat serwera został podpisany przy użyciu słabego algorytmu podpisu.</translation>
<translation id="2774256287122201187">Możesz kontynuować. Jeśli otworzysz tę stronę, ostrzeżenie nie będzie wyświetlane przez pięć minut.</translation>
<translation id="277499241957683684">Brak rekordu urządzenia</translation>
<translation id="2835170189407361413">Wyczyść formularz</translation>
-<translation id="2855922900409897335">Zweryfikuj kartę <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Zweryfikuj kartę <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego. Zegar Twojego komputera jest obecnie ustawiony na <ph name="CURRENT_TIME" />. Czy to poprawny czas? Jeśli nie, ustaw go, a następnie odśwież stronę.</translation>
+<translation id="2922350208395188000">Nie można sprawdzić certyfikatu serwera.</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="2958431318199492670">Konfiguracja sieci jest niezgodna ze standardem ONC. Jej fragmenty mogły nie zostać zaimportowane.</translation>
<translation id="2972581237482394796">&amp;Ponów</translation>
-<translation id="3010559122411665027">Pozycja listy „<ph name="ENTRY_INDEX"/>”: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Pozycja listy „<ph name="ENTRY_INDEX" />”: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Nieprawidłowy typ zasady</translation>
<translation id="3105172416063519923">Identyfikator zasobu:</translation>
<translation id="3145945101586104090">Dekodowanie odpowiedzi nie powiodło się</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Wyspa</translation>
<translation id="3219579145727097045">Wpisz datę ważności i czterocyfrowy kod CVC widoczny na przodzie karty</translation>
-<translation id="3228969707346345236">Tłumaczenie nie powiodło się, ponieważ strona jest już w języku: <ph name="LANGUAGE"/>.</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="3228969707346345236">Tłumaczenie nie powiodło się, ponieważ strona jest już w języku: <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Cofnij zmianę kolejności</translation>
+<translation id="3286538390144397061">Uruchom ponownie teraz</translation>
<translation id="333371639341676808">Zapobiegaj wyświetlaniu dodatkowych okien dialogowych na tej stronie.</translation>
-<translation id="3369366829301677151">Zaktualizuj i zweryfikuj kartę <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">ustawienia</translation>
+<translation id="3369192424181595722">Błąd zegara</translation>
+<translation id="3369366829301677151">Zaktualizuj i zweryfikuj kartę <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Anulowano obsługę</translation>
<translation id="3377188786107721145">Podczas przetwarzania zasady wystąpił błąd</translation>
<translation id="3380365263193509176">Nieznany błąd</translation>
<translation id="3380864720620200369">Identyfikator klienta:</translation>
<translation id="3427342743765426898">&amp;Ponów edycję</translation>
+<translation id="3435896845095436175">Włącz</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Okres pobierania:</translation>
+<translation id="3462200631372590220">Ukryj zaawansowane</translation>
+<translation id="3528171143076753409">Certyfikat serwera nie jest zaufany.</translation>
<translation id="3542684924769048008">Używaj hasła dla:</translation>
<translation id="3583757800736429874">&amp;Ponów przeniesienie</translation>
<translation id="3623476034248543066">Pokaż wartość</translation>
+<translation id="3648607100222897006">Funkcje eksperymentalne mogą w dowolnej chwili ulec zmianie, awarii lub też zostać wycofane. Nie dajemy absolutnie żadnych gwarancji dotyczących tego, co się może stać po włączeniu jednego z tych eksperymentów – równie dobrze może dojść do samozapłonu przeglądarki. Żarty żartami, ale teoretycznie jest możliwe na przykład usunięcie wszystkich Twoich danych przez przeglądarkę lub nieprzewidziane naruszenie Twojego bezpieczeństwa i prywatności. Każdy włączony eksperyment zostanie włączony dla wszystkich użytkowników tej przeglądarki. Prosimy o zachowanie ostrożności.</translation>
<translation id="3650584904733503804">Weryfikacja powiodła się</translation>
<translation id="370665806235115550">Ładowanie...</translation>
<translation id="3712624925041724820">Brak wolnych licencji</translation>
<translation id="3739623965217189342">Skopiowany link</translation>
<translation id="375403751935624634">Tłumaczenie nie powiodło się z powodu błędu serwera.</translation>
<translation id="385051799172605136">Wstecz</translation>
+<translation id="3858027520442213535">Zaktualizuj datę i godzinę</translation>
<translation id="3884278016824448484">Konflikt identyfikatorów urządzeń</translation>
<translation id="3885155851504623709">Gmina</translation>
<translation id="3934680773876859118">Nie można wczytać dokumentu PDF</translation>
<translation id="3963721102035795474">Tryb czytnika</translation>
<translation id="4030383055268325496">&amp;Cofnij dodanie</translation>
-<translation id="4058922952496707368">Klucz „<ph name="SUBKEY"/>”: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">OSTRZEŻENIE</translation>
+<translation id="4058922952496707368">Klucz „<ph name="SUBKEY" />”: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Proxy skonfigurowano do używania URL-a skryptu PAC, a nie ustalonych serwerów proxy.</translation>
<translation id="409504436206021213">Nie ładuj ponownie</translation>
<translation id="4103249731201008433">Numer seryjny urządzenia jest nieprawidłowy</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Nieprawidłowy podpis</translation>
<translation id="4269787794583293679">(Brak nazwy użytkownika)</translation>
<translation id="4300246636397505754">Propozycje rodziców</translation>
-<translation id="4372948949327679948">Oczekiwano wartości typu <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Nie udało się znaleźć artykułu</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="4394049700291259645">Wyłącz</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="443673843213245140">Korzystanie z serwera proxy jest wyłączone, ale podano konfigurację proxy.</translation>
-<translation id="4506176782989081258">Błąd sprawdzania poprawności: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Błąd sprawdzania poprawności: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Usunąć ten adres z Chrome?</translation>
<translation id="4594403342090139922">&amp;Cofnij usunięcie</translation>
<translation id="4607653538520819196">Oszczędzanie danych nie może przekazać tej strony.</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="4726672564094551039">Odśwież zasady</translation>
+<translation id="4728558894243024398">Platforma</translation>
+<translation id="4771973620359291008">Wystąpił nieznany błąd.</translation>
<translation id="4800132727771399293">Sprawdź datę ważności i kod CVC, a potem spróbuj ponownie</translation>
<translation id="4813512666221746211">Błąd sieci</translation>
+<translation id="4816492930507672669">Dopasuj do strony.</translation>
<translation id="4850886885716139402">Widok</translation>
-<translation id="4923417429809017348">Ta strona została przetłumaczona z nieznanego języka na język <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Ta strona została przetłumaczona z nieznanego języka na język <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Musi być określona.</translation>
<translation id="4968547170521245791">Nie można przekazać</translation>
-<translation id="498957508165411911">Przetłumaczyć z języka: <ph name="ORIGINAL_LANGUAGE"/> na <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Przetłumaczyć z języka: <ph name="ORIGINAL_LANGUAGE" /> na <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Nieprawidłowy stan magazynu wspomagającego</translation>
<translation id="5031870354684148875">Tłumacz Google – informacje</translation>
+<translation id="5045550434625856497">Nieprawidłowe hasło</translation>
+<translation id="5087286274860437796">Certyfikat serwera nie jest obecnie ważny.</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="5145883236150621069">W odebranej polityce znajduje się kod błędu</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="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="5199729219167945352">Eksperymenty</translation>
+<translation id="5251803541071282808">Chmura</translation>
<translation id="5295309862264981122">Potwierdź nawigację</translation>
<translation id="5299298092464848405">Podczas przetwarzania zasady wystąpił błąd</translation>
+<translation id="5316812925700871227">Obróć w lewo</translation>
<translation id="5317780077021120954">Zapisz</translation>
<translation id="536296301121032821">Zapisanie ustawień zasady nie powiodło się</translation>
-<translation id="5439770059721715174">Błąd podczas sprawdzania poprawności schematu – „<ph name="ERROR_PATH"/>”: <ph name="ERROR"/></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="5439770059721715174">Błąd podczas sprawdzania poprawności schematu – „<ph name="ERROR_PATH" />”: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Nieprawidłowy czas zasady</translation>
<translation id="5470861586879999274">&amp;Ponów edycję</translation>
<translation id="5509780412636533143">Zakładki zarządzane</translation>
<translation id="5523118979700054094">Nazwa zasady</translation>
<translation id="552553974213252141">Czy tekst został prawidłowo wyodrębniony?</translation>
<translation id="5540224163453853">Nie udało się znaleźć tego artykułu.</translation>
+<translation id="5556459405103347317">Odśwież</translation>
<translation id="5565735124758917034">Aktywny</translation>
<translation id="560412284261940334">Zarządzanie jest nieobsługiwane</translation>
<translation id="5629630648637658800">Ładowanie ustawień zasady nie powiodło się</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Bieżący użytkownik</translation>
<translation id="5813119285467412249">&amp;Ponów dodanie</translation>
<translation id="5872918882028971132">Propozycje rodziców</translation>
-<translation id="587701087903783706">Zamknij wersję na urządzenia mobilne</translation>
<translation id="59107663811261420">Karty tego typu nie są obsługiwane w Google Payments w przypadku tego sprzedawcy. Wybierz inną.</translation>
+<translation id="5975083100439434680">Pomniejsz</translation>
<translation id="5989320800837274978">Nie określono ani stałych serwerów proxy, ani adresu URL skryptu PAC.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Zamknij</translation>
+<translation id="6060685159320643512">Ostrożnie, na tych eksperymentach można się sparzyć</translation>
+<translation id="6151417162996330722">Certyfikat serwera ma za długi okres ważności.</translation>
<translation id="6154808779448689242">Zwrócony token zasady jest niezgodny z bieżącym</translation>
<translation id="6165508094623778733">Więcej informacji</translation>
<translation id="6259156558325130047">&amp;Ponów zmianę kolejności</translation>
-<translation id="6263376278284652872">Zakładki <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Zakładki <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Kod pocztowy</translation>
<translation id="6337534724793800597">Filtruj zasady według nazwy</translation>
+<translation id="6387478394221739770">Interesują Cię nowe, przydatne funkcje Chrome? Wypróbuj wersję beta ze strony chrome.com/beta.</translation>
+<translation id="6426993025560594914">Wszystkie eksperymenty są dostępne na Twojej platformie.</translation>
<translation id="6445051938772793705">Kraj</translation>
<translation id="6458467102616083041">Ignorowana, ponieważ wyszukiwarka domyślna jest wyłączona przez zasadę.</translation>
<translation id="647261751007945333">Zasady dotyczące urządzeń</translation>
<translation id="6512448926095770873">Opuść tę stronę</translation>
<translation id="6529602333819889595">&amp;Ponów usunięcie</translation>
<translation id="6550675742724504774">Opcje</translation>
-<translation id="6597614308054261376">Próbujesz otworzyć <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Oszczędzanie danych nie może obecnie przekazać tej strony.</translation>
-<translation id="6628463337424475685">Wyszukiwarka <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Próbujesz otworzyć <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Oszczędzanie danych nie może obecnie przekazać tej strony.</translation>
+<translation id="6628463337424475685">Wyszukiwarka <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Zasada jest przestarzała.</translation>
<translation id="6646897916597483132">Wpisz czterocyfrowy kod CVC widoczny na przodzie karty</translation>
+<translation id="674375294223700098">Nieznany błąd certyfikatu serwera.</translation>
<translation id="6753269504797312559">Wartość zasady</translation>
<translation id="6831043979455480757">Tłumacz</translation>
<translation id="6839929833149231406">Dzielnica</translation>
<translation id="6874604403660855544">&amp;Ponów dodanie</translation>
<translation id="6891596781022320156">Ten poziom zasad nie jest obsługiwany.</translation>
<translation id="6915804003454593391">Użytkownik:</translation>
+<translation id="6957887021205513506">Certyfikat serwera wydaje się sfałszowany.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">Alert JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Próbujesz połączyć się z domeną <ph name="DOMAIN" />, ale serwer przedstawił certyfikat, którego okres ważności jest za długi, by był wiarygodny.</translation>
<translation id="7087282848513945231">Hrabstwo</translation>
-<translation id="7108649287766967076">Tłumaczenie na <ph name="TARGET_LANGUAGE"/> nie powiodło się.</translation>
+<translation id="7108649287766967076">Tłumaczenie na <ph name="TARGET_LANGUAGE" /> nie powiodło się.</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7179921470347911571">Uruchom ponownie teraz</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="7186367841673660872">Ta strona została przetłumaczona z języka<ph name="ORIGINAL_LANGUAGE" />na język<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Wyszukaj hasło <ph name="SEARCH_TERMS"/> w witrynie <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Wyszukaj hasło <ph name="SEARCH_TERMS" /> w witrynie <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">Nie można nawiązać prywatnego połączenia z <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, ponieważ data i godzina (<ph name="DATE_AND_TIME" />) ustawione na komputerze są nieprawidłowe.</translation>
<translation id="7275334191706090484">Zakładki zarządzane</translation>
<translation id="7298195798382681320">Zalecane</translation>
<translation id="7334320624316649418">&amp;Ponów zmianę kolejności</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obowiązkowe</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="7568593326407688803">Język strony:<ph name="ORIGINAL_LANGUAGE"/>Chcesz ją przetłumaczyć?</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="7568593326407688803">Język strony:<ph name="ORIGINAL_LANGUAGE" />Chcesz ją przetłumaczyć?</translation>
<translation id="7569952961197462199">Usunąć tę kartę kredytową z Chrome?</translation>
-<translation id="7600965453749440009">Nigdy nie tłumacz z języka: <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Wartość spoza zakresu (<ph name="VALUE"/>)</translation>
+<translation id="7592362899630581445">Certyfikat serwera narusza ograniczenia dotyczące nazw.</translation>
+<translation id="7600965453749440009">Nigdy nie tłumacz z języka: <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Wartość spoza zakresu (<ph name="VALUE" />)</translation>
+<translation id="7674629440242451245">Interesują Cię nowe, przydatne funkcje Chrome? Wypróbuj wersję deweloperską ze strony chrome.com/dev.</translation>
<translation id="7752995774971033316">Niezarządzany</translation>
+<translation id="7761701407923456692">Certyfikat serwera jest niezgodny z adresem URL.</translation>
<translation id="777702478322588152">Prefektura</translation>
<translation id="7791543448312431591">Dodaj</translation>
<translation id="7805768142964895445">Stan</translation>
<translation id="7813600968533626083">Usunąć tę podpowiedź do formularza z Chrome?</translation>
<translation id="7887683347370398519">Sprawdź kod CVC i spróbuj ponownie</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Certyfikat serwera nie jest jeszcze ważny.</translation>
<translation id="7956713633345437162">Zakładki na komórce</translation>
<translation id="7961015016161918242">Nigdy</translation>
<translation id="7977590112176369853">&lt;wprowadź zapytanie&gt;</translation>
-<translation id="7983301409776629893">Zawsze tłumacz z języka: <ph name="ORIGINAL_LANGUAGE"/> na <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Zawsze tłumacz z języka: <ph name="ORIGINAL_LANGUAGE" /> na <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Zakładki na komputerze</translation>
<translation id="7995512525968007366">Nie określono</translation>
-<translation id="8034522405403831421">Język tej strony to <ph name="SOURCE_LANGUAGE"/>. Przetłumaczyć ją na <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Zastąpione przez zasady przedsiębiorstwa</translation>
+<translation id="8034522405403831421">Język tej strony to <ph name="SOURCE_LANGUAGE" />. Przetłumaczyć ją na <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Nie udało się wyświetlić artykułu.</translation>
<translation id="8091372947890762290">Aktywacja oczekuje na serwerze</translation>
<translation id="8194797478851900357">&amp;Cofnij przeniesienie</translation>
-<translation id="8201077131113104583">Nieprawidłowy URL aktualizowania dla rozszerzenia o identyfikatorze „<ph name="EXTENSION_ID"/>”.</translation>
+<translation id="8201077131113104583">Nieprawidłowy URL aktualizowania dla rozszerzenia o identyfikatorze „<ph name="EXTENSION_ID" />”.</translation>
<translation id="8208216423136871611">Nie zapisuj</translation>
<translation id="8218327578424803826">Przypisana lokalizacja:</translation>
<translation id="8249320324621329438">Ostatnie pobieranie:</translation>
+<translation id="8294431847097064396">Źródło</translation>
<translation id="8308427013383895095">Tłumaczenie nie powiodło się z powodu problemu z połączeniem sieciowym.</translation>
<translation id="8311778656528046050">Czy na pewno chcesz załadować ponownie tę stronę?</translation>
<translation id="8349305172487531364">Pasek zakładek</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Dotyczy</translation>
<translation id="8530504477309582336">Karty tego typu nie są obsługiwane w Google Payments. Wybierz inną.</translation>
<translation id="8553075262323480129">Tłumaczenie nie powiodło się, ponieważ nie można określić języka strony.</translation>
-<translation id="8571890674111243710">Trwa tłumaczenie strony na język: <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Nie można nawiązać prywatnego połączenia z <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, ponieważ data i godzina (<ph name="DATE_AND_TIME" />) ustawione na urządzeniu są nieprawidłowe.</translation>
+<translation id="8571890674111243710">Trwa tłumaczenie strony na język: <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Przywróć wszystkie ustawienia domyślne</translation>
<translation id="8713130696108419660">Błędny podpis wstępny</translation>
<translation id="8725066075913043281">Spróbuj ponownie</translation>
+<translation id="8738058698779197622">Aby nawiązać bezpieczne połączenie, Twój zegar musi mieć ustawioną prawidłową godzinę. Jest to wymagane, ponieważ certyfikaty używane do identyfikacji stron internetowych są ważne tylko przez określony czas. Ponieważ zegar Twojego urządzenia nie jest ustawiony prawidłowo, Chromium nie może zweryfikować tych certyfikatów.</translation>
<translation id="8790007591277257123">&amp;Ponów usunięcie</translation>
<translation id="8804164990146287819">Polityka prywatności</translation>
+<translation id="8820817407110198400">Zakładki</translation>
<translation id="8824019021993735287">Chrome nie może obecnie zweryfikować karty. Spróbuj ponownie później.</translation>
<translation id="8834246243508017242">Włącz Autouzupełnianie z kontaktami…</translation>
<translation id="883848425547221593">Inne zakładki</translation>
+<translation id="884923133447025588">Nie znaleziono mechanizmu unieważniania.</translation>
<translation id="8866481888320382733">Podczas przetwarzania ustawień zasady wystąpił błąd</translation>
<translation id="8876793034577346603">Przetwarzanie konfiguracji sieci nie powiodło się.</translation>
<translation id="8891727572606052622">Nieprawidłowy tryb proxy</translation>
-<translation id="8940229512486821554">Uruchom polecenie rozszerzenia <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Eksperyment jest niedostępny na Twojej platformie.</translation>
+<translation id="8903921497873541725">Powiększ</translation>
+<translation id="8932102934695377596">Twój zegar się spóźnia</translation>
+<translation id="8940229512486821554">Uruchom polecenie rozszerzenia <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Ważność certyfikatu serwera wygasła.</translation>
<translation id="8988760548304185580">Wpisz datę ważności i trzycyfrowy kod CVC widoczny na odwrocie karty</translation>
-<translation id="9020542370529661692">Ta strona została przetłumaczona na <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="901974403500617787">Flagi stosowane w całym systemie może ustawić tylko właściciel: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Ta strona została przetłumaczona na <ph name="TARGET_LANGUAGE" />.</translation>
+<translation id="9049981332609050619">Podjęto próbę nawiązania połączenia z witryną <ph name="DOMAIN" />, jednak serwer przedstawił nieprawidłowy certyfikat.</translation>
<translation id="9125941078353557812">Wpisz trzycyfrowy kod CVC widoczny na odwrocie karty</translation>
<translation id="9137013805542155359">Pokaż tekst oryginalny</translation>
<translation id="9148507642005240123">&amp;Cofnij edycję</translation>
<translation id="9154176715500758432">Pozostań na tej stronie</translation>
<translation id="9170848237812810038">&amp;Cofnij</translation>
+<translation id="917450738466192189">Certyfikat serwera jest nieprawidłowy.</translation>
+<translation id="9187827965378254003">Ups, wygląda na to, że nie ma obecnie dostępnych żadnych eksperymentów.</translation>
<translation id="9207861905230894330">Nie udało się dodać artykułu.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">WYCZYŚĆ FORMULARZ</translation>
+<translation id="988159990683914416">Build</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_pt-BR.xtb b/chromium/components/strings/components_strings_pt-BR.xtb
index 0f8da7ebdca..4db9fa74a62 100644
--- a/chromium/components/strings/components_strings_pt-BR.xtb
+++ b/chromium/components/strings/components_strings_pt-BR.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="pt-BR">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pt-BR">
+<translation id="1032854598605920125">Girar no sentido horário</translation>
<translation id="1055184225775184556">&amp;Desfazer adicionar</translation>
<translation id="106701514854093668">Favoritos do computador</translation>
-<translation id="1103523840287552314">Sempre traduzir do <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Ajustar à largura</translation>
+<translation id="1103523840287552314">Sempre traduzir do <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Desfazer reordenar</translation>
<translation id="111844081046043029">Tem certeza de que deseja sair desta página?</translation>
<translation id="112840717907525620">Cache da política OK</translation>
<translation id="1132774398110320017">Configurações de preenchimento automático do Google Chrome...</translation>
-<translation id="1152921474424827756">Acessar uma <ph name="BEGIN_LINK"/>cópia em cache<ph name="END_LINK"/> de <ph name="URL"/></translation>
+<translation id="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="1152921474424827756">Acessar uma <ph name="BEGIN_LINK" />cópia em cache<ph name="END_LINK" /> de <ph name="URL" /></translation>
+<translation id="121201262018556460">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado que contém uma chave fraca. Um invasor pode ter violado a chave privada, e o servidor pode não ser o servidor que você esperava (você pode estar se comunicando com um invasor).</translation>
<translation id="1227224963052638717">Política desconhecida.</translation>
<translation id="1227633850867390598">Ocultar valor</translation>
<translation id="1228893227497259893">Identificador de entidade incorreto</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Domínio de inscrição:</translation>
<translation id="1344588688991793829">Configurações de preenchimento automático do Chromium...</translation>
<translation id="1426410128494586442">Sim</translation>
+<translation id="1430915738399379752">Imprimir</translation>
<translation id="1455235771979731432">Houve um problema na verificação do seu cartão. Verifique a conexão com a Internet e tente novamente.</translation>
<translation id="1491151370853475546">Atualizar esta página</translation>
<translation id="1549470594296187301">O JavaScript deve ser ativado para usar este recurso.</translation>
-<translation id="1639239467298939599">Carregando</translation>
<translation id="1640180200866533862">Políticas de usuário</translation>
<translation id="1644184664548287040">A configuração de rede é inválida e não pôde ser importada.</translation>
-<translation id="1693754753824026215">A página em <ph name="SITE"/> diz:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o certificado de segurança dele expirou ontem. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor. O relógio do seu computador está definido para <ph name="CURRENT_DATE" />. Essa data está correta? Se não estiver, corrija o relógio do sistema e depois atualize esta página.}one{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele expirou há # dias. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor. O relógio do seu computador está definido para <ph name="CURRENT_DATE" />. Essa data está correta? Se não estiver, corrija o relógio do sistema e depois atualize esta página.}other{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele expirou há # dias. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor. O relógio do seu computador está definido para <ph name="CURRENT_DATE" />. Essa data está correta? Se não estiver, corrija o relógio do sistema e depois atualize esta página.}}</translation>
+<translation id="168841957122794586">O certificado do servidor contém uma chave de criptografia fraca.</translation>
+<translation id="1693754753824026215">A página em <ph name="SITE" /> diz:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança não é confiável para o sistema operacional do seu dispositivo. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
<translation id="1821930232296380041">Solicitação ou parâmetros de solicitação inválidos</translation>
-<translation id="1853748787962613237">Falha ao exibir artigo.</translation>
<translation id="1871208020102129563">O proxy foi configurado para utilizar servidores de proxy fixo e não um URL de script .pac.</translation>
-<translation id="1875753206475436906">tipo de heurística: <ph name="HEURISTIC_TYPE"/>
- tipo de servidor: <ph name="SERVER_TYPE"/>
- assinatura do campo: <ph name="FIELD_SIGNATURE"/>
- assinatura do formulário: <ph name="FORM_SIGNATURE"/>
- código do experimento: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Ir para <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Favoritos de <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Ir para <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Favoritos de <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Erro de serialização</translation>
+<translation id="1974060860693918893">Avançado</translation>
<translation id="2025186561304664664">O proxy está configurado em configuração automática.</translation>
<translation id="2025623846716345241">Confirmar atualização</translation>
-<translation id="2030481566774242610">Você quis dizer <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Você quis dizer <ph name="LINK" />?</translation>
<translation id="2053553514270667976">CEP</translation>
<translation id="20817612488360358">As configurações de proxy do sistema são definidas para serem utilizadas, mas uma configuração explícita de proxy também foi especificada.</translation>
<translation id="2094505752054353250">Incompatibilidade de domínio</translation>
<translation id="2096368010154057602">Departamento</translation>
<translation id="2113977810652731515">Cartão</translation>
-<translation id="2114841414352855701">Ignorado porque foi substituído por <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Ignorado porque foi substituído por <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Cliente nativo</translation>
<translation id="213826338245044447">Favoritos do Google Mobile</translation>
+<translation id="2171101176734966184">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado assinado usando um algoritmo de assinatura fraco. Isso significa que as credenciais de segurança apresentadas pelo servidor podem ter sido forjadas, e talvez o servidor não seja o esperado (talvez você esteja se comunicando com um invasor).</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2212735316055980242">Política não encontrada</translation>
<translation id="2213606439339815911">Buscando entradas...</translation>
<translation id="225207911366869382">Este valor está obsoleto para esta política.</translation>
<translation id="2262243747453050782">Erro HTTP</translation>
-<translation id="2270192940992995399">Falha ao encontrar artigo.</translation>
-<translation id="2328300916057834155">Favorito inválido ignorado no índice <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Experiências não disponíveis</translation>
+<translation id="229702904922032456">Um certificado de raiz ou intermediário expirou.</translation>
+<translation id="2328300916057834155">Favorito inválido ignorado no índice <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Outros favoritos</translation>
<translation id="2359808026110333948">Continuar</translation>
<translation id="2367567093518048410">Nível</translation>
+<translation id="2384307209577226199">Padrão da empresa</translation>
+<translation id="2386255080630008482">O certificado do servidor foi revogado.</translation>
<translation id="2392959068659972793">Mostrar políticas sem valor definido</translation>
<translation id="2396249848217231973">&amp;Desfazer exclusão</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="2455981314101692989">Esta página da web desativou o preenchimento automático para este formulário.</translation>
<translation id="2479410451996844060">URL de pesquisa inválido.</translation>
+<translation id="2491120439723279231">O certificado do servidor contém erros.</translation>
<translation id="2495083838625180221">Analisador JSON</translation>
<translation id="2498091847651709837">Digitalizar novo cartão</translation>
<translation id="2556876185419854533">&amp;Desfazer editar</translation>
-<translation id="2581221116934462656">Deseja que <ph name="PRODUCT_NAME"/> ofereça a tradução de páginas em <ph name="LANGUAGE_NAME"/> deste site na próxima vez?</translation>
+<translation id="2581221116934462656">Deseja que <ph name="PRODUCT_NAME" /> ofereça a tradução de páginas em <ph name="LANGUAGE_NAME" /> deste site na próxima vez?</translation>
<translation id="2587841377698384444">Código da API do diretório:</translation>
<translation id="2597378329261239068">Este documento está protegido por senha. Digite a senha.</translation>
+<translation id="2625385379895617796">Seu relógio está adiantado</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2653659639078652383">Enviar</translation>
<translation id="2704283930420550640">O valor não corresponde ao formato.</translation>
<translation id="2721148159707890343">Solicitação bem-sucedida</translation>
+<translation id="2728127805433021124">O certificado do servidor é assinado com um algoritmo de assinatura fraco.</translation>
<translation id="2774256287122201187">Você pode prosseguir. Se prosseguir para a página, este aviso não aparecerá novamente por cinco minutos.</translation>
<translation id="277499241957683684">Registro de dispositivo não encontrado</translation>
<translation id="2835170189407361413">Limpar formulário</translation>
-<translation id="2855922900409897335">Verificar seu <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Verificar seu <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança do servidor expirou. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor. O relógio do seu computador está definido para <ph name="CURRENT_TIME" /> no momento. Ele está certo? Caso não esteja, corrija o relógio do seu sistema e depois recarregue esta página.</translation>
+<translation id="2922350208395188000">O certificado do servidor não pode ser verificado.</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="2958431318199492670">A configuração de rede não está de acordo com o padrão ONC. Partes da configuração podem não ser importadas.</translation>
<translation id="2972581237482394796">&amp;Refazer</translation>
-<translation id="3010559122411665027">Entrada de lista &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Entrada de lista "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Tipo de política incorreto</translation>
<translation id="3105172416063519923">Código do recurso:</translation>
<translation id="3145945101586104090">Falha ao decodificar resposta</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ilha</translation>
<translation id="3219579145727097045">Insira a data de validade e o CVC de quatro dígitos que aparece na parte frontal do seu cartão</translation>
-<translation id="3228969707346345236">A tradução falhou porque a página já está em <ph name="LANGUAGE"/>.</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="3228969707346345236">A tradução falhou porque a página já está em <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Desfazer reordenar</translation>
+<translation id="3286538390144397061">Reiniciar agora</translation>
<translation id="333371639341676808">Impedir que esta página crie caixas de diálogo adicionais.</translation>
-<translation id="3369366829301677151">Atualize e verifique seu <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">configurações</translation>
+<translation id="3369192424181595722">Erro do relógio</translation>
+<translation id="3369366829301677151">Atualize e verifique seu <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Desprovisionado</translation>
<translation id="3377188786107721145">Erro de análise da política</translation>
<translation id="3380365263193509176">Erro desconhecido</translation>
<translation id="3380864720620200369">ID do cliente:</translation>
<translation id="3427342743765426898">&amp;Refazer editar</translation>
+<translation id="3435896845095436175">Ativar</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Buscar intervalo:</translation>
+<translation id="3462200631372590220">Ocultar detalhes</translation>
+<translation id="3528171143076753409">O certificado do servidor não é confiável.</translation>
<translation id="3542684924769048008">Usar senha para:</translation>
<translation id="3583757800736429874">&amp;Refazer mover</translation>
<translation id="3623476034248543066">Mostrar valor</translation>
+<translation id="3648607100222897006">Estes recursos experimentais podem ser alterados, cancelados ou desaparecer a qualquer momento. Não oferecemos qualquer garantia sobre o que possa acontecer ao ativar algum desses experimentos: seu navegador pode inclusive entrar em combustão espontânea. Brincadeiras à parte, o navegador pode excluir todos seus dados ou comprometer sua segurança e privacidade de maneira inesperada. Experimentos ativados serão habilitados para todos os usuários do navegador, portanto tenha cautela ao prosseguir.</translation>
<translation id="3650584904733503804">Validação bem-sucedida</translation>
<translation id="370665806235115550">Carregando...</translation>
<translation id="3712624925041724820">Licenças esgotadas</translation>
<translation id="3739623965217189342">Link que você copiou</translation>
<translation id="375403751935624634">A tradução falhou devido a um erro no servidor.</translation>
<translation id="385051799172605136">Voltar</translation>
+<translation id="3858027520442213535">Atualizar data e hora</translation>
<translation id="3884278016824448484">Identificador de dispositivo em conflito</translation>
<translation id="3885155851504623709">Paróquia</translation>
<translation id="3934680773876859118">Falha ao carregar o documento PDF</translation>
<translation id="3963721102035795474">Modo leitor</translation>
<translation id="4030383055268325496">&amp;Desfazer adicionar</translation>
-<translation id="4058922952496707368">Chave &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">AVISO</translation>
+<translation id="4058922952496707368">Chave "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">A configuração do proxy definida utiliza um URL de script .pac, e não servidores proxy fixos.</translation>
<translation id="409504436206021213">Não atualizar</translation>
<translation id="4103249731201008433">O número de série do dispositivo é inválido</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Assinatura inválida</translation>
<translation id="4269787794583293679">Sem nome de usuário</translation>
<translation id="4300246636397505754">Sugestões para pais</translation>
-<translation id="4372948949327679948">Valor <ph name="VALUE_TYPE"/> esperado.</translation>
+<translation id="4325863107915753736">Falha ao encontrar artigo</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="4394049700291259645">Desativar</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="443673843213245140">O uso de um proxy está desativado, mas uma configuração explícita de proxy é especificada.</translation>
-<translation id="4506176782989081258">Erro de validação: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Erro de validação: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Remover endereço do Chrome?</translation>
<translation id="4594403342090139922">&amp;Desfazer exclusão</translation>
<translation id="4607653538520819196">A Economia de dados não consegue utilizar esta página com proxy.</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="4726672564094551039">Atualizar políticas</translation>
+<translation id="4728558894243024398">Plataforma</translation>
+<translation id="4771973620359291008">Ocorreu um erro desconhecido.</translation>
<translation id="4800132727771399293">Verifique sua data de validade e seu CVC e tente novamente</translation>
<translation id="4813512666221746211">Erro na rede</translation>
+<translation id="4816492930507672669">Ajustar à página</translation>
<translation id="4850886885716139402">Visualizar</translation>
-<translation id="4923417429809017348">Esta página foi traduzida de um idioma desconhecido para o <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Esta página foi traduzida de um idioma desconhecido para o <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Deve ser especificado.</translation>
<translation id="4968547170521245791">Não é possível usar o proxy</translation>
-<translation id="498957508165411911">Traduzir de <ph name="ORIGINAL_LANGUAGE"/> para <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Traduzir de <ph name="ORIGINAL_LANGUAGE" /> para <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Armazenamento de backup em estado inválido</translation>
<translation id="5031870354684148875">Sobre o Google Tradutor</translation>
+<translation id="5045550434625856497">Senha incorreta</translation>
+<translation id="5087286274860437796">O certificado do servidor não é válido no momento.</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="5145883236150621069">Código de erro presente na resposta da política</translation>
<translation id="5172758083709347301">Máquina</translation>
-<translation id="5179510805599951267">Não está em <ph name="ORIGINAL_LANGUAGE"/>? Informe este erro</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="5199729219167945352">Experimentos</translation>
+<translation id="5251803541071282808">Nuvem</translation>
<translation id="5295309862264981122">Confirmar navegação</translation>
<translation id="5299298092464848405">Política de análise de erros</translation>
+<translation id="5316812925700871227">Girar no sentido anti-horário</translation>
<translation id="5317780077021120954">Salvar</translation>
<translation id="536296301121032821">Falha ao armazenar as configurações da política</translation>
-<translation id="5439770059721715174">Erro de validação de esquema em &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Erro de validação de esquema em "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Carimbo de data e hora da política inválido</translation>
<translation id="5470861586879999274">&amp;Refazer editar</translation>
<translation id="5509780412636533143">Favoritos gerenciados</translation>
<translation id="5523118979700054094">Nome da política</translation>
<translation id="552553974213252141">O texto foi extraído corretamente?</translation>
<translation id="5540224163453853">Não foi possível encontrar o artigo solicitado.</translation>
+<translation id="5556459405103347317">Recarregar</translation>
<translation id="5565735124758917034">Ativo</translation>
<translation id="560412284261940334">Gerenciamento não suportado</translation>
<translation id="5629630648637658800">Falha ao carregar as configurações da política</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Usuário atual</translation>
<translation id="5813119285467412249">&amp;Refazer adicionar</translation>
<translation id="5872918882028971132">Sugestões para pais</translation>
-<translation id="587701087903783706">Fechar visualização otimizada para dispositivos móveis</translation>
<translation id="59107663811261420">Este tipo de cartão não é aceito pelo Google Payments para este comerciante. Selecione outro cartão.</translation>
+<translation id="5975083100439434680">Diminuir zoom</translation>
<translation id="5989320800837274978">Nem os servidores proxy fixos nem o URL de script .pac foram especificados.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Fechar</translation>
+<translation id="6060685159320643512">Tome cuidado, esses experimentos podem morder</translation>
+<translation id="6151417162996330722">O certificado do servidor tem um período de validade excessivamente longo.</translation>
<translation id="6154808779448689242">O token da política retornado não corresponde ao token atual</translation>
<translation id="6165508094623778733">Saiba mais</translation>
<translation id="6259156558325130047">&amp;Refazer reordenar</translation>
-<translation id="6263376278284652872">Favoritos de <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Favoritos de <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Código postal</translation>
<translation id="6337534724793800597">Filtrar políticas por nome</translation>
+<translation id="6387478394221739770">Interessado em novos recursos interessantes do Google Chrome? Veja nosso Canal Beta em chrome.com/beta.</translation>
+<translation id="6426993025560594914">Todas as experiências estão disponíveis em sua plataforma.</translation>
<translation id="6445051938772793705">País</translation>
<translation id="6458467102616083041">Ignorado porque a pesquisa padrão foi desativada por uma política.</translation>
<translation id="647261751007945333">Políticas de dispositivos</translation>
<translation id="6512448926095770873">Sair desta página</translation>
<translation id="6529602333819889595">&amp;Refazer excluir</translation>
<translation id="6550675742724504774">Opções</translation>
-<translation id="6597614308054261376">Você está tentando acessar <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. No momento, a Economia de dados não consegue utilizar esta página com proxy.</translation>
-<translation id="6628463337424475685">Pesquisa do <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Você está tentando acessar <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. No momento, a Economia de dados não consegue utilizar esta página com proxy.</translation>
+<translation id="6628463337424475685">Pesquisa do <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Esta política foi encerrada.</translation>
<translation id="6646897916597483132">Digite o CVC de quatro dígitos que aparece na parte frontal do seu cartão</translation>
+<translation id="674375294223700098">Erro, certificado de servidor desconhecido.</translation>
<translation id="6753269504797312559">Valor da política</translation>
<translation id="6831043979455480757">Traduzir</translation>
<translation id="6839929833149231406">Área</translation>
<translation id="6874604403660855544">&amp;Refazer adicionar</translation>
<translation id="6891596781022320156">O nível da política não é suportado.</translation>
<translation id="6915804003454593391">Usuário:</translation>
+<translation id="6957887021205513506">O certificado do servidor parece ser falsificado.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">Alerta JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado cujo período de validade é extremamente longo, o que não é confiável.</translation>
<translation id="7087282848513945231">Condado</translation>
-<translation id="7108649287766967076">Falha na tradução para <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="7108649287766967076">Falha na tradução para <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="7139724024395191329">Emirado</translation>
+<translation id="7179921470347911571">Reiniciar agora</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="7186367841673660872">Esta página foi traduzida de<ph name="ORIGINAL_LANGUAGE" />para<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Pesquisar <ph name="SEARCH_TERMS"/> em <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Pesquisar <ph name="SEARCH_TERMS" /> em <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">Não é possível estabelecer uma conexão privada com <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do seu computador (<ph name="DATE_AND_TIME" />) estão incorretas.</translation>
<translation id="7275334191706090484">Favoritos gerenciados</translation>
<translation id="7298195798382681320">Recomendada</translation>
<translation id="7334320624316649418">&amp;Refazer reordenar</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obrigatória</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="7568593326407688803">Esta página está em<ph name="ORIGINAL_LANGUAGE"/>Deseja traduzi-la?</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="7568593326407688803">Esta página está em<ph name="ORIGINAL_LANGUAGE" />Deseja traduzi-la?</translation>
<translation id="7569952961197462199">Remover cartão de crédito do Chrome?</translation>
-<translation id="7600965453749440009">Nunca traduzir do <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">O valor não corresponde ao período <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">O certificado do servidor viola as restrições de nome.</translation>
+<translation id="7600965453749440009">Nunca traduzir do <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">O valor não corresponde ao período <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Interessado em novos recursos interessantes do Google Chrome? Veja nosso Canal Dev em chrome.com/dev.</translation>
<translation id="7752995774971033316">Não gerenciado</translation>
+<translation id="7761701407923456692">O certificado do servidor não é compatível com o URL.</translation>
<translation id="777702478322588152">Prefeitura</translation>
<translation id="7791543448312431591">Adicionar</translation>
<translation id="7805768142964895445">Status</translation>
<translation id="7813600968533626083">Remover sugestão de formulário do Chrome?</translation>
<translation id="7887683347370398519">Verifique seu CVC e tente novamente</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">O certificado do servidor ainda não é válido.</translation>
<translation id="7956713633345437162">Favoritos do Google Mobile</translation>
<translation id="7961015016161918242">Nunca</translation>
<translation id="7977590112176369853">&lt;inserir consulta&gt;</translation>
-<translation id="7983301409776629893">Sempre traduzir <ph name="ORIGINAL_LANGUAGE"/> para <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Sempre traduzir <ph name="ORIGINAL_LANGUAGE" /> para <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Favoritos do computador</translation>
<translation id="7995512525968007366">Não especificado</translation>
-<translation id="8034522405403831421">Esta página está escrita em <ph name="SOURCE_LANGUAGE"/>. Traduzi-la para <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Modificação da empresa</translation>
+<translation id="8034522405403831421">Esta página está escrita em <ph name="SOURCE_LANGUAGE" />. Traduzi-la para <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Falha ao exibir artigo.</translation>
<translation id="8091372947890762290">A ativação está pendente no servidor</translation>
<translation id="8194797478851900357">&amp;Desfazer mover</translation>
-<translation id="8201077131113104583">URL de atualização inválido para extensão com ID &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">URL de atualização inválido para extensão com ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Não salvar</translation>
<translation id="8218327578424803826">Local designado:</translation>
<translation id="8249320324621329438">Última busca:</translation>
+<translation id="8294431847097064396">Origem</translation>
<translation id="8308427013383895095">A tradução falhou devido a um problema com a conexão de rede.</translation>
<translation id="8311778656528046050">Tem certeza de que deseja atualizar esta página?</translation>
<translation id="8349305172487531364">Barra de favoritos</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Aplicável a</translation>
<translation id="8530504477309582336">Este tipo de cartão não é aceito pelo Google Payments. Selecione outro cartão.</translation>
<translation id="8553075262323480129">A tradução falhou porque não foi possível determinar o idioma da página.</translation>
-<translation id="8571890674111243710">Traduzindo página para <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Não é possível estabelecer uma conexão privada com <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do seu dispositivo (<ph name="DATE_AND_TIME" />) estão incorretas.</translation>
+<translation id="8571890674111243710">Traduzindo página para <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Redefinir tudo para o padrão</translation>
<translation id="8713130696108419660">Assinatura inicial inválida</translation>
<translation id="8725066075913043281">Tentar novamente</translation>
+<translation id="8738058698779197622">Para estabelecer uma conexão segura, o relógio precisa ser ajustado corretamente. Isso ocorre porque os certificados que os websites usam para se identificar são válidos apenas por períodos específicos. Como o relógio do seu dispositivo está incorreto, o Chromium não pode verificar esses certificados.</translation>
<translation id="8790007591277257123">&amp;Refazer excluir</translation>
<translation id="8804164990146287819">Política de Privacidade</translation>
+<translation id="8820817407110198400">Favoritos</translation>
<translation id="8824019021993735287">Não foi possível verificar seu cartão com o Chrome neste momento. Tente novamente mais tarde.</translation>
<translation id="8834246243508017242">Ativar preenchimento automático usando os Contatos.</translation>
<translation id="883848425547221593">Outros favoritos</translation>
+<translation id="884923133447025588">Nenhum mecanismo de revogação encontrado.</translation>
<translation id="8866481888320382733">Configurações da política de análise de erros</translation>
<translation id="8876793034577346603">Falha ao analisar a configuração de rede.</translation>
<translation id="8891727572606052622">Modo de proxy inválido.</translation>
-<translation id="8940229512486821554">Executar o comando <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Esta experiência não está disponível na sua plataforma.</translation>
+<translation id="8903921497873541725">Aumentar zoom</translation>
+<translation id="8932102934695377596">Seu relógio está atrasado</translation>
+<translation id="8940229512486821554">Executar o comando <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">O certificado do servidor expirou.</translation>
<translation id="8988760548304185580">Insira a data de validade e o CVC de três dígitos que aparece na parte de trás do seu cartão</translation>
-<translation id="9020542370529661692">Esta página foi traduzida para <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Sinalizações aplicáveis a todo o sistema podem ser definidas apenas pelo proprietário: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Esta página foi traduzida para <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado inválido.</translation>
<translation id="9125941078353557812">Digite o CVC de três dígitos encontrados na parte de trás do seu cartão</translation>
<translation id="9137013805542155359">Mostrar original</translation>
<translation id="9148507642005240123">&amp;Desfazer editar</translation>
<translation id="9154176715500758432">Permanecer nesta página</translation>
<translation id="9170848237812810038">&amp;Desfazer</translation>
+<translation id="917450738466192189">O certificado do servidor é inválido.</translation>
+<translation id="9187827965378254003">Que pena, parece que não há experimentos disponíveis no momento.</translation>
<translation id="9207861905230894330">Falha ao adicionar artigo.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">LIMPAR FORMULÁRIO</translation>
+<translation id="988159990683914416">Versão do desenvolvedor</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_pt-PT.xtb b/chromium/components/strings/components_strings_pt-PT.xtb
index 21f718eeb5a..1a2574ad486 100644
--- a/chromium/components/strings/components_strings_pt-PT.xtb
+++ b/chromium/components/strings/components_strings_pt-PT.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="pt-PT">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pt-PT">
+<translation id="1032854598605920125">Rodar para a direita</translation>
<translation id="1055184225775184556">&amp;Anular adição</translation>
<translation id="106701514854093668">Marcadores do Ambiente de Trabalho</translation>
-<translation id="1103523840287552314">Traduzir sempre <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Ajustar à largura</translation>
+<translation id="1103523840287552314">Traduzir sempre <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Anular reordenação</translation>
<translation id="111844081046043029">Tem a certeza de que pretende sair desta página?</translation>
<translation id="112840717907525620">Cache da política OK</translation>
<translation id="1132774398110320017">Definições de Preenchimento automático do Chrome...</translation>
-<translation id="1152921474424827756">Aceda a uma <ph name="BEGIN_LINK"/>cópia em cache<ph name="END_LINK"/> de <ph name="URL"/></translation>
+<translation id="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="1152921474424827756">Aceda a uma <ph name="BEGIN_LINK" />cópia em cache<ph name="END_LINK" /> de <ph name="URL" /></translation>
+<translation id="121201262018556460">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado que contém uma chave fraca. Um utilizador mal intencionado poderá ter quebrado a chave privada e o servidor pode não ser o servidor esperado (pode estar a comunicar com um utilizador mal intencionado).</translation>
<translation id="1227224963052638717">Política desconhecida.</translation>
<translation id="1227633850867390598">Esconder o valor</translation>
<translation id="1228893227497259893">Identificador de entidade errado</translation>
@@ -14,65 +20,78 @@
<translation id="1339601241726513588">Domínio de inscrição:</translation>
<translation id="1344588688991793829">Definições de preenchimento automático do Chromium…</translation>
<translation id="1426410128494586442">Sim</translation>
+<translation id="1430915738399379752">Imprimir</translation>
<translation id="1455235771979731432">Ocorreu um erro ao validar o cartão. Verifique a sua ligação à Internet e tente novamente.</translation>
<translation id="1491151370853475546">Atualizar esta Página</translation>
<translation id="1549470594296187301">É necessário ativar o JavaScript para utilizar esta funcionalidade.</translation>
-<translation id="1639239467298939599">A carregar</translation>
<translation id="1640180200866533862">Políticas do utilizador</translation>
<translation id="1644184664548287040">A configuração de rede é inválida e não pode ser importada.</translation>
-<translation id="1693754753824026215">A página em <ph name="SITE"/> indica:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o seu certificado de segurança expirou ontem. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação. O relógio do seu computador está atualmente configurado para <ph name="CURRENT_DATE" />. Será que isso está correto? Em caso negativo, deve corrigir o relógio do seu sistema e depois atualizar esta página.}other{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o seu certificado de segurança expirou há # dias. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação. O relógio do seu computador está atualmente configurado para <ph name="CURRENT_DATE" />. Será que isso está correto? Em caso negativo, deve corrigir o relógio do seu sistema e depois atualizar esta página.}}</translation>
+<translation id="168841957122794586">O certificado do servidor contém uma chave criptográfica fraca.</translation>
+<translation id="1693754753824026215">A página em <ph name="SITE" /> indica:</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="1734864079702812349">Amex</translation>
+<translation id="1753706481035618306">Número de página</translation>
+<translation id="1763864636252898013">Este servidor não conseguiu provar que é o domínio <ph name="DOMAIN" />; o sistema operativo do seu dispositivo não confia no respetivo certificado de segurança. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.</translation>
<translation id="1821930232296380041">Pedido ou parâmetros do pedido inválidos</translation>
-<translation id="1853748787962613237">Falha ao apresentar o artigo.</translation>
<translation id="1871208020102129563">O proxy está definido para utilizar servidores proxy fixos e não um URL de script .pac.</translation>
-<translation id="1875753206475436906">tipo de heurística: <ph name="HEURISTIC_TYPE"/>
- tipo de servidor: <ph name="SERVER_TYPE"/>
- assinatura no campo: <ph name="FIELD_SIGNATURE"/>
- assinatura no formulário: <ph name="FORM_SIGNATURE"/>
- id da experiência: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Aceder a <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Marcadores de <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Aceder a <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Marcadores de <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Erro de serialização</translation>
+<translation id="1974060860693918893">Avançadas</translation>
<translation id="2025186561304664664">O proxy está definido para configuração automática.</translation>
<translation id="2025623846716345241">Confirmar Atualização</translation>
-<translation id="2030481566774242610">Será que quis dizer <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Será que quis dizer <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Código postal</translation>
<translation id="20817612488360358">As definições de proxy do sistema estão definidas para serem utilizadas, mas também está especificada uma configuração de proxy explícita.</translation>
<translation id="2094505752054353250">Falta de correspondência de domínio</translation>
<translation id="2096368010154057602">Departamento</translation>
<translation id="2113977810652731515">Cartão</translation>
-<translation id="2114841414352855701">Ignorada porque foi substituída por <ph name="POLICY_NAME"/> .</translation>
+<translation id="2114841414352855701">Ignorada porque foi substituída por <ph name="POLICY_NAME" /> .</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Marcadores de Telemóvel</translation>
+<translation id="2171101176734966184">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado assinado utilizando um algoritmo de assinatura fraco. Significa que as credenciais de segurança apresentadas pelo servidor podem ter sido falsificadas e que o servidor pode não ser aquele que pretende (pode estar a comunicar com um utilizador mal intencionado).</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2212735316055980242">Política não encontrada</translation>
<translation id="2213606439339815911">A obter entradas...</translation>
<translation id="225207911366869382">Este valor está desatualizado para esta política.</translation>
<translation id="2262243747453050782">Erro HTTP</translation>
-<translation id="2270192940992995399">Falha ao encontrar o artigo.</translation>
-<translation id="2328300916057834155">Marcador inválido ignorado no índice <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Experiências Indisponíveis</translation>
+<translation id="229702904922032456">Um certificado de raiz ou intermédio expirou.</translation>
+<translation id="2328300916057834155">Marcador inválido ignorado no índice <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Outros marcadores</translation>
<translation id="2359808026110333948">Continuar</translation>
<translation id="2367567093518048410">Nível</translation>
+<translation id="2384307209577226199">Predefinição empresarial</translation>
+<translation id="2386255080630008482">O certificado do servidor foi revogado.</translation>
<translation id="2392959068659972793">Apresentar políticas sem valor definido</translation>
<translation id="2396249848217231973">&amp;Anular eliminação</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="2455981314101692989">Esta página Web desactivou o preenchimento automático para este formulário.</translation>
<translation id="2479410451996844060">URL de pesquisa inválido.</translation>
+<translation id="2491120439723279231">O certificado do servidor contém erros.</translation>
<translation id="2495083838625180221">Analisador JSON</translation>
<translation id="2498091847651709837">Digitalizar novo cartão</translation>
<translation id="2556876185419854533">&amp;Anular edição</translation>
-<translation id="2581221116934462656">Pretende que o <ph name="PRODUCT_NAME"/> se ofereça para traduzir as páginas em <ph name="LANGUAGE_NAME"/> deste site da próxima vez?</translation>
+<translation id="2581221116934462656">Pretende que o <ph name="PRODUCT_NAME" /> se ofereça para traduzir as páginas em <ph name="LANGUAGE_NAME" /> deste site da próxima vez?</translation>
<translation id="2587841377698384444">ID da API de diretório:</translation>
<translation id="2597378329261239068">Este documento está protegido por palavra-passe. Introduza uma palavra-passe.</translation>
+<translation id="2625385379895617796">O seu relógio está adiantado</translation>
<translation id="2639739919103226564">Estado:</translation>
+<translation id="2653659639078652383">Submeter</translation>
<translation id="2704283930420550640">O valor não corresponde ao formato.</translation>
<translation id="2721148159707890343">Pedido com êxito</translation>
+<translation id="2728127805433021124">O certificado do servidor foi assinado utilizando um algoritmo de assinatura fraco.</translation>
<translation id="2774256287122201187">Pode continuar. Se avançar para a página, este aviso só volta a aparecer dentro de cinco minutos.</translation>
<translation id="277499241957683684">Registo do dispositivo em falta</translation>
<translation id="2835170189407361413">Limpar formulário</translation>
-<translation id="2855922900409897335">Valide o seu cartão <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Valide o seu cartão <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Este servidor não conseguir provar que é o domínio <ph name="DOMAIN" />; o respetivo certificado de segurança expirou. Isto pode ser o resultado de uma configuração incorreta ou de um atacante a intercetar a sua ligação. Atualmente, o relógio do computador está definido para as <ph name="CURRENT_TIME" />. Esta hora parece-lhe correta? Em caso negativo, corrija o relógio do sistema e, em seguida, atualize esta página.</translation>
+<translation id="2922350208395188000">Não é possível verificar o certificado do servidor.</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="2958431318199492670">A configuração de rede não cumpre a norma ONC. Partes da configuração podem não ser importadas.</translation>
<translation id="2972581237482394796">&amp;Repetir</translation>
-<translation id="3010559122411665027">Entrada da lista &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Entrada da lista "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Tipo de política incorreto</translation>
<translation id="3105172416063519923">ID de recurso:</translation>
<translation id="3145945101586104090">Falha ao descodificar resposta</translation>
@@ -80,32 +99,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ilha</translation>
<translation id="3219579145727097045">Introduza a data de validade e o Código de Segurança/CVC de quatro dígitos que se encontram na parte da frente do cartão</translation>
-<translation id="3228969707346345236">Não foi possível traduzir, porque a página já está em <ph name="LANGUAGE"/>.</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="3228969707346345236">Não foi possível traduzir, porque a página já está em <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Anular reordenação</translation>
+<translation id="3286538390144397061">Reiniciar agora</translation>
<translation id="333371639341676808">Evitar que esta página crie caixas de diálogo adicionais.</translation>
-<translation id="3369366829301677151">Atualizar e validar o <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">definições</translation>
+<translation id="3369192424181595722">Erro de relógio</translation>
+<translation id="3369366829301677151">Atualizar e validar o <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Desaprovisionado</translation>
<translation id="3377188786107721145">Erro de análise da política</translation>
<translation id="3380365263193509176">Erro desconhecido</translation>
<translation id="3380864720620200369">ID do Cliente:</translation>
<translation id="3427342743765426898">&amp;Refazer edição</translation>
+<translation id="3435896845095436175">Ativar</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Intervalo de obtenção:</translation>
+<translation id="3462200631372590220">Ocultar avançadas</translation>
+<translation id="3528171143076753409">O certificado do servidor não é fidedigno.</translation>
<translation id="3542684924769048008">Utilizar palavra-passe para:</translation>
<translation id="3583757800736429874">&amp;Refazer movimentação</translation>
<translation id="3623476034248543066">Apresentar o valor</translation>
+<translation id="3648607100222897006">Estas funcionalidades experimentais podem mudar, deixar de funcionar ou desaparecer a qualquer momento. Não nos responsabilizamos pelo que possa acontecer se ativar uma destas funcionalidades experimentais e o navegador pode até entrar em combustão espontânea. Brincadeiras à parte, o navegador pode eliminar todos os dados ou a sua segurança e privacidade podem ficar comprometidas de formas inesperadas. Todas as experiências que ativar serão ativadas para todos os utilizadores deste navegador. Continue com cuidado.</translation>
<translation id="3650584904733503804">Validação com êxito</translation>
<translation id="370665806235115550">A carregar...</translation>
<translation id="3712624925041724820">Licenças esgotadas</translation>
<translation id="3739623965217189342">Link copiado por si</translation>
<translation id="375403751935624634">A tradução falhou devido a um erro do servidor.</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>
<translation id="3885155851504623709">Freguesia</translation>
<translation id="3934680773876859118">Falha ao carregar o documento em PDF</translation>
<translation id="3963721102035795474">Modo de leitor</translation>
<translation id="4030383055268325496">&amp;Anular adição</translation>
-<translation id="4058922952496707368">Chave &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">AVISO</translation>
+<translation id="4058922952496707368">Chave "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">A configuração do proxy está definida para utilizar um URL de script .pac e não servidores proxy fixos.</translation>
<translation id="409504436206021213">Não Atualizar</translation>
<translation id="4103249731201008433">Número de série do dispositivo é inválido</translation>
@@ -118,40 +147,56 @@
<translation id="4258748452823770588">Assinatura incorreta</translation>
<translation id="4269787794583293679">(Sem nome de utilizador)</translation>
<translation id="4300246636397505754">Sugestões superiores</translation>
-<translation id="4372948949327679948">Valor <ph name="VALUE_TYPE"/> esperado.</translation>
+<translation id="4325863107915753736">Falha ao encontrar o artigo</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="4394049700291259645">Desactivar</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="443673843213245140">A utilização de um proxy está desativada, mas existe uma configuração de proxy explícita especificada.</translation>
-<translation id="4506176782989081258">Erro de validação: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Erro de validação: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Pretende remover o endereço do Chrome?</translation>
<translation id="4594403342090139922">&amp;Anular eliminação</translation>
<translation id="4607653538520819196">A Poupança de dados não consegue utilizar esta página com proxy.</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="4726672564094551039">Recarregar políticas</translation>
+<translation id="4728558894243024398">Plataforma</translation>
+<translation id="4771973620359291008">Ocorreu um erro desconhecido.</translation>
<translation id="4800132727771399293">Verifique a data de validade e o Código de Segurança/CVC e tente novamente</translation>
<translation id="4813512666221746211">Erro de rede</translation>
+<translation id="4816492930507672669">Ajustar à página</translation>
<translation id="4850886885716139402">Ver</translation>
-<translation id="4923417429809017348">Esta página foi traduzida de um idioma desconhecido para <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Esta página foi traduzida de um idioma desconhecido para <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Tem de ser especificado.</translation>
<translation id="4968547170521245791">Não é possível utilizar com proxy</translation>
-<translation id="498957508165411911">Traduzir de <ph name="ORIGINAL_LANGUAGE"/> para <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Traduzir de <ph name="ORIGINAL_LANGUAGE" /> para <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Armazenamento de segurança em mau estado</translation>
<translation id="5031870354684148875">Acerca do Google Tradutor</translation>
+<translation id="5045550434625856497">Palavra-passe incorreta</translation>
+<translation id="5087286274860437796">De momento, o certificado do servidor não é válido.</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="5145883236150621069">Código de erro presente na resposta da política</translation>
<translation id="5172758083709347301">Equipamento</translation>
-<translation id="5179510805599951267">Não está em <ph name="ORIGINAL_LANGUAGE"/>? Comunicar este erro</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="5199729219167945352">Experiências</translation>
+<translation id="5251803541071282808">Nuvem</translation>
<translation id="5295309862264981122">Confirmar navegação</translation>
<translation id="5299298092464848405">Erro ao analisar a política</translation>
+<translation id="5316812925700871227">Rodar para a esquerda</translation>
<translation id="5317780077021120954">Guardar</translation>
<translation id="536296301121032821">Falha ao armazenar as definições da política</translation>
-<translation id="5439770059721715174">Erro de validação de esquema em &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Erro de validação de esquema em "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Carimbo de data/hora da política incorreto</translation>
<translation id="5470861586879999274">&amp;Refazer edição</translation>
<translation id="5509780412636533143">Marcadores geridos</translation>
<translation id="5523118979700054094">Nome da política</translation>
<translation id="552553974213252141">O texto foi extraído corretamente?</translation>
<translation id="5540224163453853">Não foi possível encontrar o artigo solicitado.</translation>
+<translation id="5556459405103347317">Recarregar</translation>
<translation id="5565735124758917034">Ativo</translation>
<translation id="560412284261940334">Gestão não suportada</translation>
<translation id="5629630648637658800">Falha ao carregar as definições da política</translation>
@@ -159,46 +204,56 @@
<translation id="5720705177508910913">Utilizador atual</translation>
<translation id="5813119285467412249">&amp;Refazer adição</translation>
<translation id="5872918882028971132">Sugestões superiores</translation>
-<translation id="587701087903783706">Fechar a vista compatível com dispositivos móveis</translation>
<translation id="59107663811261420">O Google Payments não é compatível com este tipo de cartão para este comerciante. Selecione outro cartão.</translation>
+<translation id="5975083100439434680">Reduzir</translation>
<translation id="5989320800837274978">Não foram especificados servidores proxy fixos nem um URL de script .pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Fechar</translation>
+<translation id="6060685159320643512">Tenha cuidado, estas experiências podem morder</translation>
+<translation id="6151417162996330722">O certificado do servidor tem um período de validade demasiado longo.</translation>
<translation id="6154808779448689242">O token da política devolvido não corresponde ao token atual</translation>
<translation id="6165508094623778733">Saiba mais</translation>
<translation id="6259156558325130047">&amp;Refazer reordenação</translation>
-<translation id="6263376278284652872">Marcadores do <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Marcadores do <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Código postal</translation>
<translation id="6337534724793800597">Filtrar políticas pelo nome</translation>
+<translation id="6387478394221739770">Está interessado nas novas e fantásticas funcionalidades do Chrome? Experimente o nosso canal beta em chrome.com/beta.</translation>
+<translation id="6426993025560594914">Todas as experiências estão disponíveis na sua plataforma!</translation>
<translation id="6445051938772793705">País</translation>
<translation id="6458467102616083041">Ignorado porque a pesquisa predefinida foi desativada pela política.</translation>
<translation id="647261751007945333">Políticas do dispositivo</translation>
<translation id="6512448926095770873">Sair desta página</translation>
<translation id="6529602333819889595">&amp;Refazer eliminação</translation>
<translation id="6550675742724504774">Opções</translation>
-<translation id="6597614308054261376">Está a tentar comunicar com <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. De momento, a Poupança de dados não consegue utilizar esta página com proxy.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Pesquisar</translation>
+<translation id="6597614308054261376">Está a tentar comunicar com <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. De momento, a Poupança de dados não consegue utilizar esta página com proxy.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Pesquisar</translation>
<translation id="6644283850729428850">Esta política está obsoleta.</translation>
<translation id="6646897916597483132">Introduza o Código de Segurança/CVC de quatro dígitos que se encontra na parte da frente do cartão</translation>
+<translation id="674375294223700098">Erro de certificado de servidor desconhecido.</translation>
<translation id="6753269504797312559">Valor da política</translation>
<translation id="6831043979455480757">Traduzir</translation>
<translation id="6839929833149231406">Área</translation>
<translation id="6874604403660855544">&amp;Refazer adição</translation>
<translation id="6891596781022320156">O nível da política não é suportado.</translation>
<translation id="6915804003454593391">Utilizador:</translation>
+<translation id="6957887021205513506">O certificado do servidor parece ser uma falsificação.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">Alerta de JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado cujo período de validade é demasiado longo para ser fidedigno.</translation>
<translation id="7087282848513945231">Condado</translation>
-<translation id="7108649287766967076">A tradução para <ph name="TARGET_LANGUAGE"/> falhou.</translation>
+<translation id="7108649287766967076">A tradução para <ph name="TARGET_LANGUAGE" /> falhou.</translation>
<translation id="7139724024395191329">Emirado</translation>
+<translation id="7179921470347911571">Reiniciar agora</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="7186367841673660872">Esta página foi traduzida de<ph name="ORIGINAL_LANGUAGE" />para<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Pesquisar <ph name="SEARCH_TERMS"/> no <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Pesquisar <ph name="SEARCH_TERMS" /> no <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">Não é possível estabelecer uma ligação privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do computador (<ph name="DATE_AND_TIME" />) estão incorretas.</translation>
<translation id="7275334191706090484">Marcadores Geridos</translation>
<translation id="7298195798382681320">Recomendado</translation>
<translation id="7334320624316649418">&amp;Refazer reordenação</translation>
@@ -209,31 +264,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obrigatório</translation>
<translation id="7542995811387359312">O preenchimento automático de cartões de crédito está desactivado, porque este formulário não utiliza uma ligação segura.</translation>
-<translation id="7568593326407688803">Esta página está em<ph name="ORIGINAL_LANGUAGE"/>Pretende traduzi-la?</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="7568593326407688803">Esta página está em<ph name="ORIGINAL_LANGUAGE" />Pretende traduzi-la?</translation>
<translation id="7569952961197462199">Pretende remover o cartão de crédito do Chrome?</translation>
-<translation id="7600965453749440009">Nunca traduzir do <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">O valor está fora do intervalo <ph name="VALUE"/> .</translation>
+<translation id="7592362899630581445">O certificado do servidor viola as restrições de nome.</translation>
+<translation id="7600965453749440009">Nunca traduzir do <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">O valor está fora do intervalo <ph name="VALUE" /> .</translation>
+<translation id="7674629440242451245">Está interessado nas novas e fantásticas funcionalidades do Chrome? Experimente o nosso canal para programadores em chrome.com/dev.</translation>
<translation id="7752995774971033316">Não gerido</translation>
+<translation id="7761701407923456692">O certificado do servidor não corresponde ao URL.</translation>
<translation id="777702478322588152">Prefeitura</translation>
<translation id="7791543448312431591">Adicionar</translation>
<translation id="7805768142964895445">Estado</translation>
<translation id="7813600968533626083">Pretende remover a sugestão do formulário do Chrome?</translation>
<translation id="7887683347370398519">Verifique o Código de Segurança/CVC e tente novamente</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">O certificado do servidor ainda não é válido.</translation>
<translation id="7956713633345437162">Marcadores do telemóvel</translation>
<translation id="7961015016161918242">Nunca</translation>
<translation id="7977590112176369853">&lt;introduzir consulta&gt;</translation>
-<translation id="7983301409776629893">Traduzir sempre do <ph name="ORIGINAL_LANGUAGE"/> para o <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Traduzir sempre do <ph name="ORIGINAL_LANGUAGE" /> para o <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Marcadores do ambiente de trabalho</translation>
<translation id="7995512525968007366">Não especificado</translation>
-<translation id="8034522405403831421">Esta página está em <ph name="SOURCE_LANGUAGE"/>. Pretende traduzi-la para <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Substituição empresarial</translation>
+<translation id="8034522405403831421">Esta página está em <ph name="SOURCE_LANGUAGE" />. Pretende traduzi-la para <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Falha ao ver o artigo.</translation>
<translation id="8091372947890762290">Ativação pendente no servidor</translation>
<translation id="8194797478851900357">&amp;Anular movimentação</translation>
-<translation id="8201077131113104583">Atualizar URL inválido para a extensão com o ID &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">Atualizar URL inválido para a extensão com o ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Não guardar</translation>
<translation id="8218327578424803826">Localização atribuída:</translation>
<translation id="8249320324621329438">Última obtenção:</translation>
+<translation id="8294431847097064396">Origem</translation>
<translation id="8308427013383895095">A tradução falhou devido a um problema com a ligação de rede.</translation>
<translation id="8311778656528046050">Tem a certeza de que pretende atualizar esta página?</translation>
<translation id="8349305172487531364">Barra de marcadores</translation>
@@ -242,25 +304,40 @@
<translation id="8488350697529856933">Aplica-se a</translation>
<translation id="8530504477309582336">O Google Payments não é compatível com este tipo de cartão. Selecione outro cartão.</translation>
<translation id="8553075262323480129">A tradução falhou porque não foi possível determinar o idioma da página.</translation>
-<translation id="8571890674111243710">A traduzir a página para <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Não é possível estabelecer uma ligação privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do seu dispositivo (<ph name="DATE_AND_TIME" />) estão incorretas.</translation>
+<translation id="8571890674111243710">A traduzir a página para <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Repor todas as predefinições</translation>
<translation id="8713130696108419660">Rubrica incorreta</translation>
<translation id="8725066075913043281">Tentar novamente</translation>
+<translation id="8738058698779197622">Para estabelecer uma ligação segura, o relógio tem de ser definido corretamente. Isto deve-se ao facto de os certificados que os Websites utilizam para se identificarem serem apenas válidos para períodos de tempo específicos. Uma vez que o relógio do seu dispositivo está incorreto, o Chromium não consegue validar estes certificados.</translation>
<translation id="8790007591277257123">&amp;Refazer eliminação</translation>
<translation id="8804164990146287819">Política de Privacidade</translation>
+<translation id="8820817407110198400">Marcadores</translation>
<translation id="8824019021993735287">Neste momento o Chrome não consegue validar o seu cartão. Tente novamente mais tarde.</translation>
<translation id="8834246243508017242">Ativar preenchimento automático utilizando os contactos...</translation>
<translation id="883848425547221593">Outros marcadores</translation>
+<translation id="884923133447025588">Não foi encontrado qualquer mecanismo de revogação.</translation>
<translation id="8866481888320382733">Erro ao analisar as definições da política</translation>
<translation id="8876793034577346603">Falha ao analisar a configuração de rede.</translation>
<translation id="8891727572606052622">Modo de proxy inválido.</translation>
-<translation id="8940229512486821554">Executar o comando: <ph name="EXTENSION_NAME"/><ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Infelizmente, esta experiência não está disponível na sua plataforma.</translation>
+<translation id="8903921497873541725">Ampliar</translation>
+<translation id="8932102934695377596">O seu relógio está atrasado</translation>
+<translation id="8940229512486821554">Executar o comando: <ph name="EXTENSION_NAME" /><ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">O certificado do servidor expirou.</translation>
<translation id="8988760548304185580">Introduza a data de validade e o Código de Segurança/CVC de três dígitos no verso do cartão</translation>
-<translation id="9020542370529661692">Esta página foi traduzida para <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Os sinalizadores que se aplicam a todo o sistema apenas podem ser definidos pelo proprietário: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Esta página foi traduzida para <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado inválido.</translation>
<translation id="9125941078353557812">Introduza o Código de Segurança/CVC de três dígitos que se encontra no verso do cartão</translation>
<translation id="9137013805542155359">Mostrar original</translation>
<translation id="9148507642005240123">&amp;Anular edição</translation>
<translation id="9154176715500758432">Permanecer nesta página</translation>
<translation id="9170848237812810038">An&amp;ular</translation>
+<translation id="917450738466192189">O certificado do servidor é inválido.</translation>
+<translation id="9187827965378254003">Parece que não há experiências disponíveis atualmente.</translation>
<translation id="9207861905230894330">Falha ao adicionar o artigo.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">LIMPAR FORMULÁRIO</translation>
+<translation id="988159990683914416">Compilação de programador</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ro.xtb b/chromium/components/strings/components_strings_ro.xtb
index b2279bf0378..c92f5f98800 100644
--- a/chromium/components/strings/components_strings_ro.xtb
+++ b/chromium/components/strings/components_strings_ro.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ro">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ro">
+<translation id="1032854598605920125">Rotește în sensul acelor de ceasornic</translation>
<translation id="1055184225775184556">&amp;Anulați adăugarea</translation>
<translation id="106701514854093668">Marcaje desktop</translation>
-<translation id="1103523840287552314">Tradu întotdeauna din <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Încadrează pe lățime</translation>
+<translation id="1103523840287552314">Tradu întotdeauna din <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Anulați reordonarea</translation>
<translation id="111844081046043029">Sigur vrei să ieși de pe această pagină?</translation>
<translation id="112840717907525620">Memoria cache pentru politică este OK</translation>
<translation id="1132774398110320017">Setări de completare automată în Chrome...</translation>
-<translation id="1152921474424827756">Accesați o <ph name="BEGIN_LINK"/>copie păstrată în memoria cache<ph name="END_LINK"/> a site-ului <ph name="URL"/></translation>
+<translation id="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="1152921474424827756">Accesați o <ph name="BEGIN_LINK" />copie păstrată în memoria cache<ph name="END_LINK" /> a site-ului <ph name="URL" /></translation>
+<translation id="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="1227224963052638717">Politică necunoscută.</translation>
<translation id="1227633850867390598">Ascundeți valoarea</translation>
<translation id="1228893227497259893">Identificator greșit pentru entitate</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Domeniu de înregistrare:</translation>
<translation id="1344588688991793829">Setări de completare automată în Chromium...</translation>
<translation id="1426410128494586442">Da</translation>
+<translation id="1430915738399379752">Printează</translation>
<translation id="1455235771979731432">A apărut o eroare la confirmarea cardului. Verifică conexiunea la internet și încearcă din nou.</translation>
<translation id="1491151370853475546">Reîncărcați această pagină</translation>
<translation id="1549470594296187301">Trebuie să activezi JavaScript pentru a folosi această funcție.</translation>
-<translation id="1639239467298939599">Se încarcă</translation>
<translation id="1640180200866533862">Politici privind utilizatorii</translation>
<translation id="1644184664548287040">Configurația rețelei este nevalidă și nu a putut fi importată.</translation>
-<translation id="1693754753824026215">Pagina de la <ph name="SITE"/> afișează mesajul:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate a expirat ieri. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. În prezent, ora computerului este setată la <ph name="CURRENT_DATE" />. Este corect? Dacă nu este, corectează ora sistemului și actualizează pagina.}few{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate a expirat acum # zile. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. În prezent, ora computerului este setată la <ph name="CURRENT_DATE" />. Este corect? Dacă nu este, corectează ora sistemului și actualizează pagina.}other{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate a expirat acum # de zile. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. În prezent, ora computerului este setată la <ph name="CURRENT_DATE" />. Este corect? Dacă nu este, corectează ora sistemului și actualizează pagina.}}</translation>
+<translation id="168841957122794586">Certificatul de server conține o cheie criptografică slabă.</translation>
+<translation id="1693754753824026215">Pagina de la <ph name="SITE" /> afișează mesajul:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; sistemul de operare al dispozitivului nu consideră că certificatul său de securitate este de încredere. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator.</translation>
<translation id="1821930232296380041">Solicitarea sau parametrii săi sunt greșiți</translation>
-<translation id="1853748787962613237">Articolul nu a fost afișat.</translation>
<translation id="1871208020102129563">Configurația proxy este setată să utilizeze servere proxy fixe, și nu o adresă URL pentru scripturi .pac.</translation>
-<translation id="1875753206475436906">tip euristic: <ph name="HEURISTIC_TYPE"/>
- tip de server: <ph name="SERVER_TYPE"/>
- semnătură câmp: <ph name="FIELD_SIGNATURE"/>
- semnătură formular: <ph name="FORM_SIGNATURE"/>
- ID experiment: „<ph name="EXPERIMENT_ID"/>”</translation>
-<translation id="194030505837763158">Accesați <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Marcaje <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Accesați <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Marcaje <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Eroare de serializare</translation>
+<translation id="1974060860693918893">Avansat</translation>
<translation id="2025186561304664664">Proxy-ul este setat la Configurat automat.</translation>
<translation id="2025623846716345241">Confirmați reîncărcarea</translation>
-<translation id="2030481566774242610">Ați dorit să scrieți <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Ați dorit să scrieți <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Cod zip</translation>
<translation id="20817612488360358">Setările proxy de sistem sunt setate pentru a fi utilizate, dar o configurație explicită pentru proxy este, de asemenea, specificată.</translation>
<translation id="2094505752054353250">Nepotrivire domeniu</translation>
<translation id="2096368010154057602">Departament</translation>
<translation id="2113977810652731515">Card</translation>
-<translation id="2114841414352855701">Politica este ignorată, deoarece a fost înlocuită de <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Politica este ignorată, deoarece a fost înlocuită de <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Client nativ</translation>
<translation id="213826338245044447">Marcaje mobile</translation>
+<translation id="2171101176734966184">Ați încercat să accesați <ph name="DOMAIN" />, dar serverul a furnizat un certificat semnat utilizând un algoritm de semnare slab. Aceasta însemnă că este posibil ca acreditările de securitate furnizate de server să fie falsificate, iar serverul să nu fie cel așteptat (este posibil să comunicați cu un atacator).</translation>
<translation id="2181821976797666341">Politici</translation>
<translation id="2212735316055980242">Politica nu a fost găsită</translation>
<translation id="2213606439339815911">Se preiau intrările...</translation>
<translation id="225207911366869382">Valoarea este învechită pentru această politică.</translation>
<translation id="2262243747453050782">Eroare HTTP</translation>
-<translation id="2270192940992995399">Articolul nu a fost găsit.</translation>
-<translation id="2328300916057834155">Marcaj nevalid ignorat la indexul <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Experimente indisponibile</translation>
+<translation id="229702904922032456">Un certificat rădăcină sau intermediar a expirat.</translation>
+<translation id="2328300916057834155">Marcaj nevalid ignorat la indexul <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Alte marcaje</translation>
<translation id="2359808026110333948">Continuă</translation>
<translation id="2367567093518048410">Nivel</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="2396249848217231973">&amp;Anulați ștergerea</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="2455981314101692989">Această pagină web a dezactivat completarea automată a formularului.</translation>
<translation id="2479410451996844060">Adresă URL de căutare nevalidă.</translation>
+<translation id="2491120439723279231">Certificatul serverului conține erori.</translation>
<translation id="2495083838625180221">Analizor JSON</translation>
<translation id="2498091847651709837">Scanează un card nou</translation>
<translation id="2556876185419854533">&amp;Anulați editarea</translation>
-<translation id="2581221116934462656">Dorești ca produsul <ph name="PRODUCT_NAME"/> să ofere traducerea paginilor din <ph name="LANGUAGE_NAME"/> de pe acest site data următoare când îl accesezi?</translation>
+<translation id="2581221116934462656">Dorești ca produsul <ph name="PRODUCT_NAME" /> să ofere traducerea paginilor din <ph name="LANGUAGE_NAME" /> de pe acest site data următoare când îl accesezi?</translation>
<translation id="2587841377698384444">ID-ul API-ului Directory:</translation>
<translation id="2597378329261239068">Acest document este protejat cu parolă. Introdu o parolă.</translation>
+<translation id="2625385379895617796">Ora este setată în viitor</translation>
<translation id="2639739919103226564">Stare:</translation>
+<translation id="2653659639078652383">Trimite</translation>
<translation id="2704283930420550640">Valoarea nu se potrivește cu formatul.</translation>
<translation id="2721148159707890343">Solicitarea a reușit</translation>
+<translation id="2728127805433021124">Certificatul serverului este semnat utilizând un algoritm de semnătură slab.</translation>
<translation id="2774256287122201187">Poți continua. Dacă accesezi pagina, acest avertisment nu se va mai afișa în următoarele 5 minute.</translation>
<translation id="277499241957683684">Lipsește o înregistrare pentru gadget</translation>
<translation id="2835170189407361413">Golește formularul</translation>
-<translation id="2855922900409897335">Confirmă <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Confirmă <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; certificatul său de securitate a expirat. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator. În prezent, ceasul computerului este setat la <ph name="CURRENT_TIME" />. Este corect? Dacă nu, trebuie să corectezi ora sistemului, apoi să actualizezi pagina.</translation>
+<translation id="2922350208395188000">Certificatul serverului nu poate fi verificat.</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="2958431318199492670">Configurația rețelei nu respectă standardul ONC. Este posibil ca anumite părți ale configurației să nu fie importate.</translation>
<translation id="2972581237482394796">&amp;Repetă</translation>
-<translation id="3010559122411665027">Intrarea din listă „<ph name="ENTRY_INDEX"/>”: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Intrarea din listă „<ph name="ENTRY_INDEX" />”: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Tip de politică greșit</translation>
<translation id="3105172416063519923">ID articol:</translation>
<translation id="3145945101586104090">Răspunsul nu a putut fi decodificat</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Insulă</translation>
<translation id="3219579145727097045">Introdu data de expirare și codul CVC alcătuit din 4 cifre înscris pe fața cardului</translation>
-<translation id="3228969707346345236">Pagina nu a fost tradusă, deoarece aceasta este deja în <ph name="LANGUAGE"/>.</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="3228969707346345236">Pagina nu a fost tradusă, deoarece aceasta este deja în <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Anulați reordonarea</translation>
+<translation id="3286538390144397061">Repornește acum</translation>
<translation id="333371639341676808">Împiedică această pagină să creeze alte casete de dialog.</translation>
-<translation id="3369366829301677151">Actualizează și confirmă cardul <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">setări</translation>
+<translation id="3369192424181595722">Eroare de ceas</translation>
+<translation id="3369366829301677151">Actualizează și confirmă cardul <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Scos din uz</translation>
<translation id="3377188786107721145">Eroare la analizarea politicii</translation>
<translation id="3380365263193509176">Eroare necunoscută</translation>
<translation id="3380864720620200369">Cod de client:</translation>
<translation id="3427342743765426898">&amp;Repetați editarea</translation>
+<translation id="3435896845095436175">Activează</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Interval de preluare:</translation>
+<translation id="3462200631372590220">Ascundeți detaliile avansate</translation>
+<translation id="3528171143076753409">Certificatul serverului nu este de încredere.</translation>
<translation id="3542684924769048008">Folosește parola pentru:</translation>
<translation id="3583757800736429874">&amp;Repetați mutarea</translation>
<translation id="3623476034248543066">Afișați valoarea</translation>
+<translation id="3648607100222897006">Aceste funcții experimentale pot oricând să se schimbe, să nu mai funcționeze sau să dispară. Nu oferim absolut nicio garanție cu privire la efectele activării acestor experimente. Se poate chiar ca browserul să se defecteze brusc. Lăsând gluma la o parte, browserul poate să șteargă toate datele sau securitatea și confidențialitatea datelor se pot compromite într-un mod neașteptat. Toate experimentele pe care le activezi vor fi activate pentru toți utilizatorii acestui browser. Continuă cu prudență.</translation>
<translation id="3650584904733503804">Validarea a reușit</translation>
<translation id="370665806235115550">Se încarcă…</translation>
<translation id="3712624925041724820">Licențe epuizate</translation>
<translation id="3739623965217189342">Linkul copiat de tine</translation>
<translation id="375403751935624634">Traducerea nu a reușit din cauza unei erori de server.</translation>
<translation id="385051799172605136">Înapoi</translation>
+<translation id="3858027520442213535">Actualizează data și ora</translation>
<translation id="3884278016824448484">Identificator de gadget în conflict</translation>
<translation id="3885155851504623709">Parohie</translation>
<translation id="3934680773876859118">Documentul PDF nu a fost încărcat</translation>
<translation id="3963721102035795474">Modul Cititor</translation>
<translation id="4030383055268325496">&amp;Anulați adăugarea</translation>
-<translation id="4058922952496707368">Cheie „<ph name="SUBKEY"/>”: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">AVERTISMENT</translation>
+<translation id="4058922952496707368">Cheie „<ph name="SUBKEY" />”: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Configurația pentru proxy este setată să utilizeze o adresă URL pentru scripturi .pac, și nu servere proxy fixe.</translation>
<translation id="409504436206021213">Nu reîncărcați</translation>
<translation id="4103249731201008433">Numărul de serie al gadgetului este nevalid</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Semnătură greșită</translation>
<translation id="4269787794583293679">(Niciun nume de utilizator)</translation>
<translation id="4300246636397505754">Sugestii parentale</translation>
-<translation id="4372948949327679948">Se aștepta valoarea <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Articolul nu a fost găsit</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="4394049700291259645">Dezactivează</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="443673843213245140">Utilizarea unui proxy este dezactivată, dar o configurare proxy este specificată în mod explicit.</translation>
-<translation id="4506176782989081258">Eroare de validare: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Eroare de validare: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Elimini adresa din Chrome?</translation>
<translation id="4594403342090139922">&amp;Anulați ștergerea</translation>
<translation id="4607653538520819196">Această pagină nu poate fi gestionată prin proxy de Economizorul de date.</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="4726672564094551039">Reîncărcați politicile</translation>
+<translation id="4728558894243024398">Platformă</translation>
+<translation id="4771973620359291008">A apărut o eroare necunoscută.</translation>
<translation id="4800132727771399293">Verifică data de expirare și codul CVC și încearcă din nou</translation>
<translation id="4813512666221746211">Eroare de rețea</translation>
+<translation id="4816492930507672669">Încadrați în pagină</translation>
<translation id="4850886885716139402">Afișează</translation>
-<translation id="4923417429809017348">Această pagină a fost tradusă dintr-o limbă necunoscută în <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Această pagină a fost tradusă dintr-o limbă necunoscută în <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Valoarea trebuie specificată.</translation>
<translation id="4968547170521245791">Nu se poate folosi un proxy</translation>
-<translation id="498957508165411911">Se traduce din <ph name="ORIGINAL_LANGUAGE"/> în <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Se traduce din <ph name="ORIGINAL_LANGUAGE" /> în <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Depozit de fundal în stare nevalidă</translation>
<translation id="5031870354684148875">Despre Google Traducere</translation>
+<translation id="5045550434625856497">Parolă incorectă</translation>
+<translation id="5087286274860437796">Momentan, certificatul serverului este nevalid.</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="5145883236150621069">Răspunsul pentru politică include un cod de eroare</translation>
<translation id="5172758083709347301">Computer</translation>
-<translation id="5179510805599951267">Nu este în <ph name="ORIGINAL_LANGUAGE"/>? Semnalează această eroare.</translation>
+<translation id="5179510805599951267">Nu este în <ph name="ORIGINAL_LANGUAGE" />? Semnalează această eroare.</translation>
<translation id="5190835502935405962">Bară de marcaje</translation>
+<translation id="5199729219167945352">Experimente</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">Confirmă navigarea</translation>
<translation id="5299298092464848405">Eroare la analizarea politicii</translation>
+<translation id="5316812925700871227">Rotește în sens invers acelor de ceasornic</translation>
<translation id="5317780077021120954">Salvează</translation>
<translation id="536296301121032821">Setările pentru politică nu au putut fi stocate</translation>
-<translation id="5439770059721715174">Eroare de validare a schemei la „<ph name="ERROR_PATH"/>”: <ph name="ERROR"/></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="5439770059721715174">Eroare de validare a schemei la „<ph name="ERROR_PATH" />”: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Marcaj temporal greșit pentru politică</translation>
<translation id="5470861586879999274">&amp;Repetați editarea</translation>
<translation id="5509780412636533143">Marcaje gestionate</translation>
<translation id="5523118979700054094">Numele politicii</translation>
<translation id="552553974213252141">Textul a fost extras corect?</translation>
<translation id="5540224163453853">Articolul solicitat nu poate fi găsit.</translation>
+<translation id="5556459405103347317">Reîncarcă</translation>
<translation id="5565735124758917034">Activ</translation>
<translation id="560412284261940334">Gestionarea nu este acceptată</translation>
<translation id="5629630648637658800">Setările pentru politică nu au putut fi încărcate</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Utilizator curent</translation>
<translation id="5813119285467412249">&amp;Repetați adăugarea</translation>
<translation id="5872918882028971132">Sugestii parentale</translation>
-<translation id="587701087903783706">Închide afișarea pentru dispozitive mobile</translation>
<translation id="59107663811261420">Acest tip de card nu este acceptat de Google Payments pentru acest comerciant. Selectează alt card.</translation>
+<translation id="5975083100439434680">Micșorează</translation>
<translation id="5989320800837274978">Nu sunt specificate nici servere proxy fixe și nici o adresă URL pentru scripturi .pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Închide</translation>
+<translation id="6060685159320643512">Atenție, aceste experimente pot produce daune</translation>
+<translation id="6151417162996330722">Certificatul de server are o perioadă de validitate prea lungă.</translation>
<translation id="6154808779448689242">Indicativul returnat pentru politică nu corespunde cu indicativul actual</translation>
<translation id="6165508094623778733">Află mai multe</translation>
<translation id="6259156558325130047">&amp;Repetați reordonarea</translation>
-<translation id="6263376278284652872">Marcaje <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Marcaje <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Cod poștal</translation>
<translation id="6337534724793800597">Filtrați politicile după nume</translation>
+<translation id="6387478394221739770">Doriți să utilizați funcții Chrome noi și interesante? Încercați canalul nostru beta de la chrome.com/beta.</translation>
+<translation id="6426993025560594914">Toate experimentele sunt disponibile pe platforma dvs.!</translation>
<translation id="6445051938772793705">Țară</translation>
<translation id="6458467102616083041">Valoare ignorată, deoarece politica a dezactivat căutarea prestabilită.</translation>
<translation id="647261751007945333">Politici privind dispozitivele</translation>
<translation id="6512448926095770873">Ieși de pe această pagină</translation>
<translation id="6529602333819889595">&amp;Repetați ștergerea</translation>
<translation id="6550675742724504774">Opțiuni</translation>
-<translation id="6597614308054261376">Încerci să accesezi <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. În prezent, această pagină nu poate fi gestionată prin proxy de Economizorul de date.</translation>
-<translation id="6628463337424475685">Căutare <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Încerci să accesezi <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. În prezent, această pagină nu poate fi gestionată prin proxy de Economizorul de date.</translation>
+<translation id="6628463337424475685">Căutare <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Această politică este învechită.</translation>
<translation id="6646897916597483132">Introdu codul CVC alcătuit din 4 cifre înscris pe fața a cardului</translation>
+<translation id="674375294223700098">Eroare de certificat de server necunoscută.</translation>
<translation id="6753269504797312559">Valoarea politicii</translation>
<translation id="6831043979455480757">Tradu</translation>
<translation id="6839929833149231406">Zonă</translation>
<translation id="6874604403660855544">&amp;Repetați adăugarea</translation>
<translation id="6891596781022320156">Nivelul politicii nu este acceptat.</translation>
<translation id="6915804003454593391">Utilizator:</translation>
+<translation id="6957887021205513506">Certificatul serverului pare a fi un fals.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">Alertă JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Ai încercat să accesezi <ph name="DOMAIN" />, dar serverul a prezentat un certificat a cărui perioadă de validitate este prea lungă pentru a fi de încredere.</translation>
<translation id="7087282848513945231">Comitat</translation>
-<translation id="7108649287766967076">Traducerea în <ph name="TARGET_LANGUAGE"/> nu a reușit.</translation>
+<translation id="7108649287766967076">Traducerea în <ph name="TARGET_LANGUAGE" /> nu a reușit.</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7179921470347911571">Relansează acum</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="7186367841673660872">Această pagină a fost tradusă din <ph name="ORIGINAL_LANGUAGE" /> în <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Caută <ph name="SEARCH_TERMS"/> pe <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Caută <ph name="SEARCH_TERMS" /> pe <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">O conexiune privată la <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nu poate fi stabilită, deoarece data și ora computerului (<ph name="DATE_AND_TIME" />) sunt incorecte.</translation>
<translation id="7275334191706090484">Marcaje gestionate</translation>
<translation id="7298195798382681320">Recomandate</translation>
<translation id="7334320624316649418">&amp;Repetați reordonarea</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obligatorie</translation>
<translation id="7542995811387359312">Completarea automată a cardului de credit este dezactivată, deoarece acest formular nu utilizează o conexiune sigură.</translation>
-<translation id="7568593326407688803">Această pagină este în <ph name="ORIGINAL_LANGUAGE"/> Vrei să fie tradusă?</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="7568593326407688803">Această pagină este în <ph name="ORIGINAL_LANGUAGE" /> Vrei să fie tradusă?</translation>
<translation id="7569952961197462199">Elimini cardul de credit din Chrome?</translation>
-<translation id="7600965453749440009">Nu traduce niciodată din <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Valoarea este în afara intervalului <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Certificatul serverului încalcă limitările privind numele.</translation>
+<translation id="7600965453749440009">Nu traduce niciodată din <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Valoarea este în afara intervalului <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Doriți să utilizați funcții Chrome noi și interesante? Încercați canalul nostru pentru dezvoltatori, de la chrome.com/dev.</translation>
<translation id="7752995774971033316">Negestionat</translation>
+<translation id="7761701407923456692">Certificatul serverului nu se potrivește cu adresa URL.</translation>
<translation id="777702478322588152">Prefectură</translation>
<translation id="7791543448312431591">Adaugă</translation>
<translation id="7805768142964895445">Stare</translation>
<translation id="7813600968533626083">Elimini sugestia pentru formular din Chrome?</translation>
<translation id="7887683347370398519">Verifică codul CVC și încearcă din nou</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Certificatul serverului nu este încă valid.</translation>
<translation id="7956713633345437162">Marcaje mobile</translation>
<translation id="7961015016161918242">Niciodată</translation>
<translation id="7977590112176369853">&lt;introdu interogarea&gt;</translation>
-<translation id="7983301409776629893">Tradu întotdeauna din <ph name="ORIGINAL_LANGUAGE"/> în <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Tradu întotdeauna din <ph name="ORIGINAL_LANGUAGE" /> în <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Marcaje desktop</translation>
<translation id="7995512525968007366">Nespecificată</translation>
-<translation id="8034522405403831421">Această pagină este în <ph name="SOURCE_LANGUAGE"/>. Doriți traducere în <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Modificare la nivel de companie</translation>
+<translation id="8034522405403831421">Această pagină este în <ph name="SOURCE_LANGUAGE" />. Doriți traducere în <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Articolul nu a fost vizualizat.</translation>
<translation id="8091372947890762290">Se așteaptă activarea pe server</translation>
<translation id="8194797478851900357">&amp;Anulați mutarea</translation>
-<translation id="8201077131113104583">Adresa URL pentru actualizarea extensiei cu ID-ul „<ph name="EXTENSION_ID"/>” nu este validă.</translation>
+<translation id="8201077131113104583">Adresa URL pentru actualizarea extensiei cu ID-ul „<ph name="EXTENSION_ID" />” nu este validă.</translation>
<translation id="8208216423136871611">Nu salva</translation>
<translation id="8218327578424803826">Locație atribuită:</translation>
<translation id="8249320324621329438">Ultima preluare:</translation>
+<translation id="8294431847097064396">Sursă</translation>
<translation id="8308427013383895095">Traducerea nu a reușit din cauza unei probleme cu conexiunea la rețea.</translation>
<translation id="8311778656528046050">Sigur doriți să reîncărcați această pagină?</translation>
<translation id="8349305172487531364">Bara de marcaje</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Se aplică pentru</translation>
<translation id="8530504477309582336">Acest tip de card nu este acceptat de Google Payments. Selectează alt card.</translation>
<translation id="8553075262323480129">Traducerea nu a reușit, deoarece nu a putut fi stabilită limba paginii.</translation>
-<translation id="8571890674111243710">Se traduce pagina în <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">O conexiune privată la <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nu poate fi stabilită, deoarece data și ora dispozitivului (<ph name="DATE_AND_TIME" />) sunt incorecte.</translation>
+<translation id="8571890674111243710">Se traduce pagina în <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Resetați-le pe toate la valorile prestabilite</translation>
<translation id="8713130696108419660">Semnătură inițială incorectă</translation>
<translation id="8725066075913043281">Încearcă din nou</translation>
+<translation id="8738058698779197622">Pentru a stabili o conexiune securizată, ceasul trebuie să fie setat corect. Aceasta deoarece certificatele pe care site-urile le folosesc pentru a se identifica sunt valabile numai pentru anumite intervale de timp. Din moment ce ora de pe dispozitiv este incorectă, Chromium nu poate verifica aceste certificate.</translation>
<translation id="8790007591277257123">&amp;Repetați ștergerea</translation>
<translation id="8804164990146287819">Politica de confidențialitate</translation>
+<translation id="8820817407110198400">Marcaje</translation>
<translation id="8824019021993735287">Momentan, Chrome nu a putut confirma cardul. Încearcă mai târziu.</translation>
<translation id="8834246243508017242">Activați completarea automată folosind Agenda…</translation>
<translation id="883848425547221593">Alte marcaje</translation>
+<translation id="884923133447025588">Nu a fost găsit niciun mecanism de revocare.</translation>
<translation id="8866481888320382733">Eroare la analizarea setărilor pentru politică</translation>
<translation id="8876793034577346603">Configurația rețelei nu a putut fi analizată.</translation>
<translation id="8891727572606052622">Mod proxy nevalid.</translation>
-<translation id="8940229512486821554">Execută comanda <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Ne pare rău, acest experiment nu este disponibil pe platforma dvs.</translation>
+<translation id="8903921497873541725">Mărește</translation>
+<translation id="8932102934695377596">Ora este setată în trecut</translation>
+<translation id="8940229512486821554">Execută comanda <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Certificatul serverului a expirat.</translation>
<translation id="8988760548304185580">Introdu data de expirare și codul CVC alcătuit din 3 cifre înscris pe spatele cardului</translation>
-<translation id="9020542370529661692">Această pagină a fost tradusă în <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Marcajele care se aplică la nivel de sistem pot fi create numai de proprietar: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Această pagină a fost tradusă în <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Ai încercat să accesezi <ph name="DOMAIN" />, dar serverul a prezentat un certificat nevalid.</translation>
<translation id="9125941078353557812">Introdu codul CVC alcătuit din 3 cifre înscris pe spatele cardului</translation>
<translation id="9137013805542155359">Afișează originalul</translation>
<translation id="9148507642005240123">&amp;Anulați editarea</translation>
<translation id="9154176715500758432">Rămâi pe pagină</translation>
<translation id="9170848237812810038">&amp;Anulează</translation>
+<translation id="917450738466192189">Certificatul serverului nu este valid.</translation>
+<translation id="9187827965378254003">Hopa! Se pare că în prezent nu există niciun experiment disponibil.</translation>
<translation id="9207861905230894330">Articolul nu a fost adăugat.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">GOLEȘTE FORMULARUL</translation>
+<translation id="988159990683914416">Versiune de programare</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ru.xtb b/chromium/components/strings/components_strings_ru.xtb
index dc994e551b0..6ccebbbdb57 100644
--- a/chromium/components/strings/components_strings_ru.xtb
+++ b/chromium/components/strings/components_strings_ru.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ru">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ru">
+<translation id="1032854598605920125">Повернуть по часовой стрелке</translation>
<translation id="1055184225775184556">&amp;Отменить добавление</translation>
<translation id="106701514854093668">Закладки на компьютере</translation>
-<translation id="1103523840287552314">Всегда переводить <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Выровнять по ширине окна</translation>
+<translation id="1103523840287552314">Всегда переводить <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Отменить изменение порядка</translation>
<translation id="111844081046043029">Вы действительно хотите покинуть эту страницу?</translation>
<translation id="112840717907525620">В кеше политики ошибок не найдено</translation>
<translation id="1132774398110320017">Настройки автозаполнения в Chrome...</translation>
-<translation id="1152921474424827756">Открыть <ph name="BEGIN_LINK"/>кешированную версию<ph name="END_LINK"/> страницы <ph name="URL"/></translation>
+<translation id="1150979032973867961">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Операционная система компьютера не доверяет его сертификату безопасности. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
+<translation id="1152921474424827756">Открыть <ph name="BEGIN_LINK" />кешированную версию<ph name="END_LINK" /> страницы <ph name="URL" /></translation>
+<translation id="121201262018556460">Вы попытались перейти на сайт <ph name="DOMAIN" />, но сервер предоставил сертификат с ненадежным ключом. Возможно, частный ключ был взломан злоумышленником, а сервер выдает себя за другой (вероятно, это атака).</translation>
<translation id="1227224963052638717">Неизвестное правило.</translation>
<translation id="1227633850867390598">Скрыть значение</translation>
<translation id="1228893227497259893">Неверный идентификатор объекта</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Регистрация домена:</translation>
<translation id="1344588688991793829">Настройки автозаполнения в Chromium...</translation>
<translation id="1426410128494586442">Да</translation>
+<translation id="1430915738399379752">Печать</translation>
<translation id="1455235771979731432">Не удалось подтвердить данные карты. Проверьте подключение к Интернету и повторите попытку.</translation>
<translation id="1491151370853475546">Обновить страницу</translation>
<translation id="1549470594296187301">Для использования этой функции необходимо включить JavaScript.</translation>
-<translation id="1639239467298939599">Загрузка</translation>
<translation id="1640180200866533862">Пользовательские правила</translation>
<translation id="1644184664548287040">Импорт невозможен: недопустимая конфигурация сети.</translation>
-<translation id="1693754753824026215">Подтвердите действие на <ph name="SITE"/></translation>
+<translation id="1655462015569774233">{1,plural, =1{Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Срок действия его сертификата безопасности истек вчера. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные. Обратите внимание, что на компьютере установлено время <ph name="CURRENT_DATE" />. Если оно неправильное, измените его и обновите страницу.}one{Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Срок действия его сертификата безопасности истек # день назад. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные. Обратите внимание, что на компьютере установлено время <ph name="CURRENT_DATE" />. Если оно неправильное, измените его и обновите страницу.}few{Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Срок действия его сертификата безопасности истек # дня назад. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные. Обратите внимание, что на компьютере установлено время <ph name="CURRENT_DATE" />. Если оно неправильное, измените его и обновите страницу.}many{Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Срок действия его сертификата безопасности истек # дней назад. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные. Обратите внимание, что на компьютере установлено время <ph name="CURRENT_DATE" />. Если оно неправильное, измените его и обновите страницу.}other{Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Срок действия его сертификата безопасности истек # дня назад. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные. Обратите внимание, что на компьютере установлено время <ph name="CURRENT_DATE" />. Если оно неправильное, измените его и обновите страницу.}}</translation>
+<translation id="168841957122794586">Сертификат сервера содержит ненадежный криптографический ключ.</translation>
+<translation id="1693754753824026215">Подтвердите действие на <ph name="SITE" /></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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Операционная система устройства не доверяет его сертификату безопасности. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
<translation id="1821930232296380041">Недопустимый запрос или неверные параметры запроса</translation>
-<translation id="1853748787962613237">Не удалось показать статью</translation>
<translation id="1871208020102129563">Выбрано использование фиксированных прокси-серверов, а не URL PAC-скрипта.</translation>
-<translation id="1875753206475436906">эвристический алгоритм: <ph name="HEURISTIC_TYPE"/>
- тип сервера: <ph name="SERVER_TYPE"/>
- подпись поля: <ph name="FIELD_SIGNATURE"/>
- подпись формы: <ph name="FORM_SIGNATURE"/>
- код теста: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Перейдите по ссылке: <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Закладки <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Перейдите по ссылке: <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Закладки <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Не удалось выполнить сериализацию</translation>
+<translation id="1974060860693918893">Дополнительно</translation>
<translation id="2025186561304664664">Прокси-сервер настраивается автоматически.</translation>
<translation id="2025623846716345241">Подтвердить обновление страницы</translation>
-<translation id="2030481566774242610">Возможно, вы имели в виду <ph name="LINK"/>.</translation>
+<translation id="2030481566774242610">Возможно, вы имели в виду <ph name="LINK" />.</translation>
<translation id="2053553514270667976">Почтовый индекс</translation>
<translation id="20817612488360358">Включены системные настройки прокси-сервера, но при этом его конфигурация задана явным образом.</translation>
<translation id="2094505752054353250">Несоответствие домена</translation>
<translation id="2096368010154057602">Округ</translation>
<translation id="2113977810652731515">Карта</translation>
-<translation id="2114841414352855701">Игнорируется, так как правило <ph name="POLICY_NAME"/> имеет приоритет.</translation>
+<translation id="2114841414352855701">Игнорируется, так как правило <ph name="POLICY_NAME" /> имеет приоритет.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Закладки на мобильном</translation>
+<translation id="2171101176734966184">Вы попытались перейти на сайт <ph name="DOMAIN" />, однако сертификат, предоставленный сервером, подписан с использованием ненадежного алгоритма. Это означает, что учетные данные безопасности могут быть поддельными, а сервер может выдавать себя за другой (вероятно, это атака).</translation>
<translation id="2181821976797666341">Правила</translation>
<translation id="2212735316055980242">Политика для устройства не найдена</translation>
<translation id="2213606439339815911">Извлечение записей…</translation>
<translation id="225207911366869382">Это значение для данного правила больше не используется.</translation>
<translation id="2262243747453050782">Ошибка HTTP</translation>
-<translation id="2270192940992995399">Не удалось найти статью</translation>
-<translation id="2328300916057834155">Пропущена недопустимая закладка, индекс <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Недоступные расширения</translation>
+<translation id="229702904922032456">Срок действия корневого или промежуточного сертификата истек.</translation>
+<translation id="2328300916057834155">Пропущена недопустимая закладка, индекс <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Другие закладки</translation>
<translation id="2359808026110333948">Далее</translation>
<translation id="2367567093518048410">Уровень</translation>
+<translation id="2384307209577226199">Для предприятий (по умолчанию)</translation>
+<translation id="2386255080630008482">Сертификат сервера отозван.</translation>
<translation id="2392959068659972793">Показывать правила, значения которых не заданы</translation>
<translation id="2396249848217231973">&amp;Отменить удаление</translation>
+<translation id="2413528052993050574">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности может быть отозван. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
<translation id="2455981314101692989">На этой веб-странице отключено автоматическое заполнение формы.</translation>
<translation id="2479410451996844060">Недействительный URL поисковой системы.</translation>
+<translation id="2491120439723279231">Сертификат сервера содержит ошибки.</translation>
<translation id="2495083838625180221">Синтаксический анализатор JSON</translation>
<translation id="2498091847651709837">Сканировать новую карту</translation>
<translation id="2556876185419854533">&amp;Отменить изменения</translation>
-<translation id="2581221116934462656">Хотите, чтобы <ph name="PRODUCT_NAME"/> всегда предлагал перевести этот сайт, когда обнаружит на его страницах <ph name="LANGUAGE_NAME"/>?</translation>
+<translation id="2581221116934462656">Хотите, чтобы <ph name="PRODUCT_NAME" /> всегда предлагал перевести этот сайт, когда обнаружит на его страницах <ph name="LANGUAGE_NAME" />?</translation>
<translation id="2587841377698384444">Идентификатор Directory API:</translation>
<translation id="2597378329261239068">Документ защищен паролем. Введите пароль.</translation>
+<translation id="2625385379895617796">Часы спешат</translation>
<translation id="2639739919103226564">Состояние:</translation>
+<translation id="2653659639078652383">Отправить</translation>
<translation id="2704283930420550640">Значение не соответствует формату.</translation>
<translation id="2721148159707890343">Запрос выполнен успешно</translation>
+<translation id="2728127805433021124">Сертификат сервера подписан с использованием ненадежного алгоритма.</translation>
<translation id="2774256287122201187">Вы можете продолжить работу. Если вы останетесь на странице, предупреждение будет показано снова через 5 минут.</translation>
<translation id="277499241957683684">Устройство не зарегистрировано</translation>
<translation id="2835170189407361413">Очистить форму</translation>
-<translation id="2855922900409897335">Подтвердите данные карты <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Подтвердите данные карты <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Срок действия его сертификата безопасности истек. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные. Обратите внимание, что на компьютере установлено время <ph name="CURRENT_TIME" />. Если оно неправильное, измените его и обновите страницу.</translation>
+<translation id="2922350208395188000">Не удается проверить сертификат сервера.</translation>
+<translation id="2941952326391522266">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности относится к <ph name="DOMAIN2" />. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
<translation id="2958431318199492670">Некоторые элементы сетевой конфигурации невозможно импортировать, поскольку она не соответствует стандарту ONC.</translation>
<translation id="2972581237482394796">&amp;Повторить</translation>
-<translation id="3010559122411665027">Элемент списка &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Элемент списка "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Неверный тип политики</translation>
<translation id="3105172416063519923">Идентификатор объекта:</translation>
<translation id="3145945101586104090">Не удалось декодировать ответ</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Остров</translation>
<translation id="3219579145727097045">Введите срок действия и четырехзначный CVC-код, указанный на лицевой стороне карты.</translation>
-<translation id="3228969707346345236">Перевод не удался, так как страница уже написана на следующем языке: <ph name="LANGUAGE"/>.</translation>
+<translation id="3225919329040284222">Сертификат не соответствует встроенным параметрам определенных сайтов с высоким уровнем безопасности.</translation>
+<translation id="3228969707346345236">Перевод не удался, так как страница уже написана на следующем языке: <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Отменить изменение порядка</translation>
+<translation id="3286538390144397061">Перезапустить сейчас</translation>
<translation id="333371639341676808">Предотвратить создание дополнительных диалоговых окон на этой странице.</translation>
-<translation id="3369366829301677151">Обновите данные карты <ph name="CREDIT_CARD"/> и подтвердите ее</translation>
+<translation id="3340978935015468852">настройках</translation>
+<translation id="3369192424181595722">Ошибка часов</translation>
+<translation id="3369366829301677151">Обновите данные карты <ph name="CREDIT_CARD" /> и подтвердите ее</translation>
<translation id="337363190475750230">Отключен</translation>
<translation id="3377188786107721145">Не удалось выполнить анализ политики</translation>
<translation id="3380365263193509176">Неизвестная ошибка</translation>
<translation id="3380864720620200369">Идентификатор клиента:</translation>
<translation id="3427342743765426898">&amp;Повторить изменения</translation>
+<translation id="3435896845095436175">Включить</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Выберите интервал:</translation>
+<translation id="3462200631372590220">Скрыть подробности</translation>
+<translation id="3528171143076753409">Сертификат сервера не является доверенным.</translation>
<translation id="3542684924769048008">Использовать пароль для:</translation>
<translation id="3583757800736429874">&amp;Повторить перемещение</translation>
<translation id="3623476034248543066">Показать значение</translation>
+<translation id="3648607100222897006">Эти экспериментальные функции в любой момент могут измениться, прекратить работу или исчезнуть. Мы не предоставляем никаких гарантий относительно возможных последствий их активации, кроме того, они могут привести к сбою браузера. Браузер может удалить все ваши данные, безопасность и конфиденциальность данных могут быть нарушены неожиданных образом. Экспериментальные функции, выбранные одним пользователем, включаются для всех пользователей браузера на компьютере. Соблюдайте осторожность.</translation>
<translation id="3650584904733503804">Проверка выполнена успешно</translation>
<translation id="370665806235115550">Загрузка...</translation>
<translation id="3712624925041724820">Недостаточно лицензий</translation>
<translation id="3739623965217189342">Скопированная ссылка</translation>
<translation id="375403751935624634">Сбой при переводе вследствие ошибки сервера.</translation>
<translation id="385051799172605136">Назад</translation>
+<translation id="3858027520442213535">Обновить дату и время</translation>
<translation id="3884278016824448484">Конфликт идентификаторов устройств</translation>
<translation id="3885155851504623709">Округ</translation>
<translation id="3934680773876859118">Не удалось загрузить документ PDF</translation>
<translation id="3963721102035795474">Режим чтения</translation>
<translation id="4030383055268325496">&amp;Отменить добавление</translation>
-<translation id="4058922952496707368">Ключ &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">Внимание!</translation>
+<translation id="4058922952496707368">Ключ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Конфигурация прокси-сервера предусматривает использование URL PAC-скриптов вместо фиксированных прокси-серверов.</translation>
<translation id="409504436206021213">Не обновлять страницу</translation>
<translation id="4103249731201008433">Серийный номер устройства недействителен</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Подпись недействительна</translation>
<translation id="4269787794583293679">(Не указано)</translation>
<translation id="4300246636397505754">Подсказки для родительских элементов</translation>
-<translation id="4372948949327679948">Ожидаемое значение: <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Не удалось найти статью</translation>
+<translation id="4372948949327679948">Ожидаемое значение: <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Вы попытались перейти на сайт <ph name="DOMAIN" />, однако сертификат, предоставленный сервером, был отозван издателем. Это означает, что учетные данные безопасности, предоставленные сервером, не заслуживают доверия. Возможно, вы имеете дело со злоумышленниками.</translation>
+<translation id="4394049700291259645">Отключить</translation>
+<translation id="4424024547088906515">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Chrome не доверяет его сертификату безопасности. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
<translation id="443673843213245140">Прокси-сервер отключен, но при этом его конфигурация задана явным образом.</translation>
-<translation id="4506176782989081258">Ошибка проверки: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Ошибка проверки: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Удалить адрес из Chrome?</translation>
<translation id="4594403342090139922">&amp;Отменить удаление</translation>
<translation id="4607653538520819196">Эту страницу нельзя открыть в режиме экономии трафика.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности содержит ошибки. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
<translation id="4726672564094551039">Повторно загрузить политики</translation>
+<translation id="4728558894243024398">Платформа</translation>
+<translation id="4771973620359291008">Произошла неизвестная ошибка.</translation>
<translation id="4800132727771399293">Проверьте срок действия и CVC-код, а затем повторите попытку</translation>
<translation id="4813512666221746211">Ошибка сети</translation>
+<translation id="4816492930507672669">По размеру страницы</translation>
<translation id="4850886885716139402">Посмотреть</translation>
-<translation id="4923417429809017348">Эта страница была автоматически переведена с неизвестного языка на <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Эта страница была автоматически переведена с неизвестного языка на <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Укажите значение.</translation>
<translation id="4968547170521245791">Невозможно использовать прокси-сервер</translation>
-<translation id="498957508165411911">Выполнить перевод (<ph name="ORIGINAL_LANGUAGE"/> &gt; <ph name="TARGET_LANGUAGE"/>)?</translation>
+<translation id="498957508165411911">Выполнить перевод (<ph name="ORIGINAL_LANGUAGE" /> &gt; <ph name="TARGET_LANGUAGE" />)?</translation>
<translation id="5019198164206649151">Данные в хранилище повреждены</translation>
<translation id="5031870354684148875">О Переводчике Google</translation>
+<translation id="5045550434625856497">Неправильный пароль</translation>
+<translation id="5087286274860437796">Сертификат сервера не действителен в настоящее время.</translation>
<translation id="5089810972385038852">Штат</translation>
+<translation id="5094747076828555589">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Chromium не доверяет его сертификату безопасности. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
<translation id="5095208057601539847">Провинция</translation>
<translation id="5145883236150621069">При проверке политики возвращен код ошибки</translation>
<translation id="5172758083709347301">Локальный компьютер</translation>
-<translation id="5179510805599951267">Это не <ph name="ORIGINAL_LANGUAGE"/>? Сообщите об ошибке</translation>
+<translation id="5179510805599951267">Это не <ph name="ORIGINAL_LANGUAGE" />? Сообщите об ошибке</translation>
<translation id="5190835502935405962">Панель закладок</translation>
+<translation id="5199729219167945352">Экспериментальные функции</translation>
+<translation id="5251803541071282808">Облако</translation>
<translation id="5295309862264981122">Подтвердите переход</translation>
<translation id="5299298092464848405">Не удалось выполнить анализ политики</translation>
+<translation id="5316812925700871227">Повернуть против часовой стрелки</translation>
<translation id="5317780077021120954">Сохранить</translation>
<translation id="536296301121032821">Не удалось сохранить настройки политики</translation>
-<translation id="5439770059721715174">Ошибка проверки схемы, <ph name="ERROR_PATH"/>: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности может быть недействителен в настоящее время. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
+<translation id="5439770059721715174">Ошибка проверки схемы, <ph name="ERROR_PATH" />: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Неверная временная метка политики</translation>
<translation id="5470861586879999274">&amp;Повторить изменения</translation>
<translation id="5509780412636533143">Управляемые закладки</translation>
<translation id="5523118979700054094">Название правила</translation>
<translation id="552553974213252141">Правильно ли извлечен текст?</translation>
<translation id="5540224163453853">Не удалось найти указанную статью</translation>
+<translation id="5556459405103347317">Перезагрузить</translation>
<translation id="5565735124758917034">Активен</translation>
<translation id="560412284261940334">Управление устройствами не поддерживается</translation>
<translation id="5629630648637658800">Не удалось применить настройки политики</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Текущий пользователь</translation>
<translation id="5813119285467412249">&amp;Повторить добавление</translation>
<translation id="5872918882028971132">Подсказки для родительских элементов</translation>
-<translation id="587701087903783706">Закрыть режим просмотра на мобильном устройстве</translation>
<translation id="59107663811261420">Сервис Google Payments не поддерживает карты этого типа для данного продавца. Выберите другую карту.</translation>
+<translation id="5975083100439434680">Уменьшить</translation>
<translation id="5989320800837274978">Ни фиксированные прокси-серверы, ни URL PAC-скриптов не указаны.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Закрыть</translation>
+<translation id="6060685159320643512">Будьте осторожны при работе с экспериментальной версией</translation>
+<translation id="6151417162996330722">Слишком долгий срок действия сертификата, предоставленного сервером.</translation>
<translation id="6154808779448689242">Возвращенный токен не соответствует имеющемуся</translation>
<translation id="6165508094623778733">Подробнее...</translation>
<translation id="6259156558325130047">&amp;Повторить изменение порядка</translation>
-<translation id="6263376278284652872">Закладки <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Закладки <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Почтовый индекс</translation>
<translation id="6337534724793800597">Фильтровать политики по названию</translation>
+<translation id="6387478394221739770">Хотите быть в курсе новинок Chrome? Выберите бета-канал на странице "chrome.com/beta".</translation>
+<translation id="6426993025560594914">На вашей платформе доступны все экспериментальные функции!</translation>
<translation id="6445051938772793705">Страна</translation>
<translation id="6458467102616083041">Игнорируется, так как поиск по умолчанию запрещен правилами.</translation>
<translation id="647261751007945333">Правила устройства</translation>
<translation id="6512448926095770873">Покинуть эту страницу</translation>
<translation id="6529602333819889595">&amp;Повторить удаление</translation>
<translation id="6550675742724504774">Параметры</translation>
-<translation id="6597614308054261376">В настоящее время сайт <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> нельзя открыть в режиме экономии трафика.</translation>
-<translation id="6628463337424475685">Поиск <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">В настоящее время сайт <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> нельзя открыть в режиме экономии трафика.</translation>
+<translation id="6628463337424475685">Поиск <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Правило устарело.</translation>
<translation id="6646897916597483132">Введите четырехзначный CVC-код, указанный на лицевой стороне карты.</translation>
+<translation id="674375294223700098">Неизвестная ошибка сертификата сервера.</translation>
<translation id="6753269504797312559">Значение правила</translation>
<translation id="6831043979455480757">Перевести</translation>
<translation id="6839929833149231406">Административный район</translation>
<translation id="6874604403660855544">&amp;Повторить добавление</translation>
<translation id="6891596781022320156">Значение правила не поддерживается.</translation>
<translation id="6915804003454593391">Пользователь:</translation>
+<translation id="6957887021205513506">Возможно, сертификат сервера фальсифицирован.</translation>
<translation id="6965382102122355670">ОК</translation>
<translation id="6965978654500191972">Устройство</translation>
<translation id="6970216967273061347">Район</translation>
<translation id="6973656660372572881">Указаны как фиксированные прокси-серверы, так и URL PAC-скриптов.</translation>
<translation id="6980028882292583085">Оповещение JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Вы попытались перейти на сайт <ph name="DOMAIN" />, но сервер предоставил не заслуживающий доверия сертификат со слишком долгим сроком действия.</translation>
<translation id="7087282848513945231">Графство</translation>
-<translation id="7108649287766967076">Не удалось выполнить перевод на <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="7108649287766967076">Не удалось выполнить перевод на <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="7139724024395191329">Эмират</translation>
+<translation id="7179921470347911571">Перезапустить</translation>
<translation id="7180611975245234373">Обновить</translation>
<translation id="7182878459783632708">Правила не заданы</translation>
-<translation id="7186367841673660872">Эта страница была переведена автоматически<ph name="ORIGINAL_LANGUAGE"/>&gt;<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="7186367841673660872">Эта страница была переведена автоматически<ph name="ORIGINAL_LANGUAGE" />&gt;<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Искать на <ph name="SITE_NAME"/> <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Искать на <ph name="SITE_NAME" /> <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Не удалось установить защищенное соединение с доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> из-за неверных настроек системных часов и календаря (<ph name="DATE_AND_TIME" />).</translation>
<translation id="7275334191706090484">Управляемые закладки</translation>
<translation id="7298195798382681320">Рекомендованные</translation>
<translation id="7334320624316649418">&amp;Повторить изменение порядка</translation>
@@ -208,32 +262,39 @@
<translation id="7485870689360869515">Данные не найдены.</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Обязательная</translation>
-<translation id="7542995811387359312">Автозаполнение данных банковской карты отключено, так как на сайте используется незащищенное соединение.</translation>
-<translation id="7568593326407688803">Язык этой страницы<ph name="ORIGINAL_LANGUAGE"/>Хотите перевести ее?</translation>
+<translation id="7542995811387359312">Автозаполнение отключено – незащищенное подключение.</translation>
+<translation id="7567204685887185387">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности мог быть выдан обманным путем. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
+<translation id="7568593326407688803">Язык этой страницы<ph name="ORIGINAL_LANGUAGE" />Хотите перевести ее?</translation>
<translation id="7569952961197462199">Удалить кредитную карту из Chrome?</translation>
-<translation id="7600965453749440009">Никогда не переводить <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Значение <ph name="VALUE"/> лежит за пределами разрешенного диапазона.</translation>
+<translation id="7592362899630581445">Сертификат сервера не соответствует ограничениям в отношении имен.</translation>
+<translation id="7600965453749440009">Никогда не переводить <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Значение <ph name="VALUE" /> лежит за пределами разрешенного диапазона.</translation>
+<translation id="7674629440242451245">Хотите быть в курсе новинок Chrome? Выберите канал обновления для разработчиков на странице "chrome.com/dev".</translation>
<translation id="7752995774971033316">Не управляется</translation>
+<translation id="7761701407923456692">Сертификат сервера не соответствует URL.</translation>
<translation id="777702478322588152">Префектура</translation>
<translation id="7791543448312431591">Добавить</translation>
<translation id="7805768142964895445">Состояние</translation>
<translation id="7813600968533626083">Удалить подсказку из Chrome?</translation>
<translation id="7887683347370398519">Проверьте CVC-код и повторите попытку</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Сертификат сервера еще не действителен.</translation>
<translation id="7956713633345437162">Закладки на мобильном</translation>
<translation id="7961015016161918242">Нет</translation>
<translation id="7977590112176369853">&lt;введите запрос&gt;</translation>
-<translation id="7983301409776629893">Всегда переводить <ph name="ORIGINAL_LANGUAGE"/> на <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Всегда переводить <ph name="ORIGINAL_LANGUAGE" /> на <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Закладки на компьютере</translation>
<translation id="7995512525968007366">Не указано</translation>
-<translation id="8034522405403831421">Язык этой страницы: <ph name="SOURCE_LANGUAGE"/>. Перевести ее на <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Для предприятий (переопределить нельзя)</translation>
+<translation id="8034522405403831421">Язык этой страницы: <ph name="SOURCE_LANGUAGE" />. Перевести ее на <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Не удалось показать статью</translation>
<translation id="8091372947890762290">Активация управления устройствами не завершена</translation>
<translation id="8194797478851900357">&amp;Отменить перемещение</translation>
-<translation id="8201077131113104583">Недействительный URL для обновления расширения с идентификатором <ph name="EXTENSION_ID"/>.</translation>
+<translation id="8201077131113104583">Недействительный URL для обновления расширения с идентификатором <ph name="EXTENSION_ID" />.</translation>
<translation id="8208216423136871611">Не сохранять</translation>
<translation id="8218327578424803826">Назначенное местоположение:</translation>
<translation id="8249320324621329438">Время последней загрузки:</translation>
+<translation id="8294431847097064396">Источник</translation>
<translation id="8308427013383895095">Перевод не завершен из-за проблем с сетевым подключением.</translation>
<translation id="8311778656528046050">Действительно обновить эту страницу?</translation>
<translation id="8349305172487531364">Панель закладок</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Объект применения</translation>
<translation id="8530504477309582336">Этот тип карт не поддерживается в Google Payments. Выберите другую карту.</translation>
<translation id="8553075262323480129">Перевод не удался, так как не удается определить язык страницы.</translation>
-<translation id="8571890674111243710">Перевод страницы на <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Не удалось установить защищенное соединение с доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> из-за неверных настроек системных часов и календаря (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="8571890674111243710">Перевод страницы на <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Восстановить настройки по умолчанию</translation>
<translation id="8713130696108419660">Недопустимая начальная подпись</translation>
<translation id="8725066075913043281">Повторить попытку</translation>
+<translation id="8738058698779197622">Для создания безопасного подключения необходимо, чтобы показания системных часов были верны. Причина в том, что сертификаты для идентификации сайтов имеют ограниченный срок действия. Если часы на устройстве неточны, Chromium не может проверить актуальность этих сертификатов.</translation>
<translation id="8790007591277257123">&amp;Повторить удаление</translation>
<translation id="8804164990146287819">Политика конфиденциальности</translation>
+<translation id="8820817407110198400">Закладки</translation>
<translation id="8824019021993735287">Не удалось проверить данные карты. Повторите попытку позже.</translation>
<translation id="8834246243508017242">Включить автозаполнение контактов…</translation>
<translation id="883848425547221593">Другие закладки</translation>
+<translation id="884923133447025588">Не обнаружен механизм отзыва.</translation>
<translation id="8866481888320382733">Не удалось выполнить анализ настроек политики</translation>
<translation id="8876793034577346603">Не удалось выполнить анализ конфигурации сети.</translation>
<translation id="8891727572606052622">Недопустимый режим работы прокси-сервера.</translation>
-<translation id="8940229512486821554">Выполнить команду расширения <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">К сожалению, данное действие невозможно выполнить на этой платформе.</translation>
+<translation id="8903921497873541725">Увеличить</translation>
+<translation id="8932102934695377596">Часы отстают</translation>
+<translation id="8940229512486821554">Выполнить команду расширения <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Сертификат сервера устарел.</translation>
<translation id="8988760548304185580">Введите срок действия и трехзначный CVC-код, указанный на обратной стороне карты.</translation>
-<translation id="9020542370529661692">Эта страница переведена на <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="901974403500617787">Системные флаги может устанавливать только владелец (<ph name="OWNER_EMAIL" />).</translation>
+<translation id="9020542370529661692">Эта страница переведена на <ph name="TARGET_LANGUAGE" />.</translation>
+<translation id="9049981332609050619">Вы попытались открыть <ph name="DOMAIN" />, однако представленный сервером сертификат недействителен.</translation>
<translation id="9125941078353557812">Введите трехзначный CVC-код, указанный на обратной стороне карты.</translation>
<translation id="9137013805542155359">Показать оригинал</translation>
<translation id="9148507642005240123">&amp;Отменить изменения</translation>
<translation id="9154176715500758432">Остаться на этой странице</translation>
<translation id="9170848237812810038">&amp;Отменить</translation>
+<translation id="917450738466192189">Сертификат сервера недействителен</translation>
+<translation id="9187827965378254003">Хм, кажется, доступных экспериментов нет.</translation>
<translation id="9207861905230894330">Не удалось добавить статью</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ОЧИСТИТЬ ФОРМУ</translation>
+<translation id="988159990683914416">Сборка для разработчиков</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_sk.xtb b/chromium/components/strings/components_strings_sk.xtb
index dc10bba8b38..dcd316cb0a5 100644
--- a/chromium/components/strings/components_strings_sk.xtb
+++ b/chromium/components/strings/components_strings_sk.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="sk">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sk">
+<translation id="1032854598605920125">Otočiť v smere hodinových ručičiek</translation>
<translation id="1055184225775184556">&amp;Vrátiť späť pridanie</translation>
<translation id="106701514854093668">Záložky plochy</translation>
-<translation id="1103523840287552314">Vždy preložiť nasledujúci jazyk: <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Prispôsobiť šírke</translation>
+<translation id="1103523840287552314">Vždy preložiť nasledujúci jazyk: <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Vrátiť späť zmenu poradia</translation>
<translation id="111844081046043029">Naozaj chcete odísť z tejto stránky?</translation>
<translation id="112840717907525620">Vyrovnávacia pamäť pravidla je v poriadku</translation>
<translation id="1132774398110320017">Nastavenia Automatického dopĺňania prehliadača Chrome...</translation>
-<translation id="1152921474424827756">Prístup ku <ph name="BEGIN_LINK"/>kópii vo vyrovnávacej pamäti<ph name="END_LINK"/> stránky <ph name="URL"/></translation>
+<translation id="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="1152921474424827756">Prístup ku <ph name="BEGIN_LINK" />kópii vo vyrovnávacej pamäti<ph name="END_LINK" /> stránky <ph name="URL" /></translation>
+<translation id="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="1227224963052638717">Neznáme pravidlo.</translation>
<translation id="1227633850867390598">Skryť hodnotu</translation>
<translation id="1228893227497259893">Nesprávny identifikátor entity</translation>
@@ -14,65 +20,78 @@
<translation id="1339601241726513588">Doména registrácie:</translation>
<translation id="1344588688991793829">Nastavenia Automatického dopĺňania prehliadača Chromium...</translation>
<translation id="1426410128494586442">Áno</translation>
+<translation id="1430915738399379752">Tlačiť</translation>
<translation id="1455235771979731432">Pri overovaní karty sa vyskytol problém. Skontrolujte svoje pripojenie k internetu a skúste to znova.</translation>
<translation id="1491151370853475546">Znova načítať stránku</translation>
<translation id="1549470594296187301">Ak chcete použiť túto funkciu, musíte povoliť JavaScript.</translation>
-<translation id="1639239467298939599">Prebieha načítavanie</translation>
<translation id="1640180200866533862">Pravidlá pre používateľa</translation>
<translation id="1644184664548287040">Konfigurácia siete je neplatná a nepodarilo sa ju importovať.</translation>
-<translation id="1693754753824026215">Stránka na lokalite <ph name="SITE"/>:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Tomuto serveru sa nepodarilo dokázať, že ide o doménu <ph name="DOMAIN" />; platnosť jej bezpečnostného certifikátu vypršala včera. Môže to byť následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útočníkom. Hodiny vášho počítača sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento čas správny? Ak nie, opravte čas na hodinách systému a potom obnovte túto stránku.}few{Tomuto serveru sa nepodarilo dokázať, že ide o doménu <ph name="DOMAIN" />; platnosť jej bezpečnostného certifikátu vypršala pred # dňami. Môže to byť následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útočníkom. Hodiny vášho počítača sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento čas správny? Ak nie, opravte čas na hodinách systému a potom obnovte túto stránku.}many{Tomuto serveru sa nepodarilo dokázať, že ide o doménu <ph name="DOMAIN" />; platnosť jej bezpečnostného certifikátu vypršala pred # dňom. Môže to byť následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útočníkom. Hodiny vášho počítača sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento čas správny? Ak nie, opravte čas na hodinách systému a potom obnovte túto stránku.}other{Tomuto serveru sa nepodarilo dokázať, že ide o doménu <ph name="DOMAIN" />; platnosť jej bezpečnostného certifikátu vypršala pred # dňami. Môže to byť následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útočníkom. Hodiny vášho počítača sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento čas správny? Ak nie, opravte čas na hodinách systému a potom obnovte túto stránku.}}</translation>
+<translation id="168841957122794586">Certifikát servera obsahuje slabý kryptografický kľúč.</translation>
+<translation id="1693754753824026215">Stránka na lokalite <ph name="SITE" />:</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="1734864079702812349">Amex</translation>
+<translation id="1753706481035618306">Číslo stránky</translation>
+<translation id="1763864636252898013">Server nedokáže overiť, či ide o doménu <ph name="DOMAIN" />, operačný systém vášho zariadenia nedôveruje jej bezpečnostnému certifikátu. Môže to byť spôsobené nesprávnou konfiguráciou alebo tým, že vaše pripojenie zachytil útočník.</translation>
<translation id="1821930232296380041">Neplatná žiadosť alebo parametre žiadosti</translation>
-<translation id="1853748787962613237">Článok sa nepodarilo zobraziť.</translation>
<translation id="1871208020102129563">Proxy je nastavené na použitie pevne daných serverov proxy, nie skriptov PAC webovej adresy.</translation>
-<translation id="1875753206475436906">typ heuristiky: <ph name="HEURISTIC_TYPE"/>
- typ servera: <ph name="SERVER_TYPE"/>
- podpis poľa: <ph name="FIELD_SIGNATURE"/>
- podpis formulára: <ph name="FORM_SIGNATURE"/>
- ID experimentu: „<ph name="EXPERIMENT_ID"/>“</translation>
-<translation id="194030505837763158">Prejdite na stránku <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Záložky (<ph name="DOMAIN"/>)</translation>
+<translation id="194030505837763158">Prejdite na stránku <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Záložky (<ph name="DOMAIN" />)</translation>
<translation id="1973335181906896915">Chyba serializácie</translation>
+<translation id="1974060860693918893">Rozšírené</translation>
<translation id="2025186561304664664">Proxy je nastavené na automatickú konfiguráciu.</translation>
<translation id="2025623846716345241">Potvrdiť opätovné načítanie</translation>
-<translation id="2030481566774242610">Mysleli ste stránku <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Mysleli ste stránku <ph name="LINK" />?</translation>
<translation id="2053553514270667976">PSČ</translation>
<translation id="20817612488360358">Používanie systémových nastavení servera proxy je nastavené, avšak je určená aj explicitná konfigurácia servera proxy.</translation>
<translation id="2094505752054353250">Domény sa nezhodujú</translation>
<translation id="2096368010154057602">Správna oblasť</translation>
<translation id="2113977810652731515">Karta</translation>
-<translation id="2114841414352855701">Ignorované, pretože bolo prepísané pravidlom <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Ignorované, pretože bolo prepísané pravidlom <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Záložky v mobile</translation>
+<translation id="2171101176734966184">Pokúsili ste sa o prístup na stránky <ph name="DOMAIN" />, server však predložil certifikát podpísaný slabým algoritmom podpisu. Znamená to, že predložené poverenia zabezpečenia mohli byť sfalšované a môže ísť o úplne iný server, než ste očakávali (môžete komunikovať s útočníkom).</translation>
<translation id="2181821976797666341">Pravidlá</translation>
<translation id="2212735316055980242">Pravidlo sa nenašlo</translation>
<translation id="2213606439339815911">Načítavanie záznamov...</translation>
<translation id="225207911366869382">Táto hodnota už pre toto pravidlo nie je podporovaná.</translation>
<translation id="2262243747453050782">Chyba protokolu HTTP</translation>
-<translation id="2270192940992995399">Článok sa nepodarilo vyhľadať.</translation>
-<translation id="2328300916057834155">Neplatná záložka v indexe <ph name="ENTRY_INDEX"/> bola ignorovaná</translation>
+<translation id="2282872951544483773">Nedostupné experimenty</translation>
+<translation id="229702904922032456">Platnosť certifikátu na odomknutie alebo sprostredkovanie vypršala.</translation>
+<translation id="2328300916057834155">Neplatná záložka v indexe <ph name="ENTRY_INDEX" /> bola ignorovaná</translation>
<translation id="2354001756790975382">Iné záložky</translation>
<translation id="2359808026110333948">Pokračovať</translation>
<translation id="2367567093518048410">Úroveň</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="2396249848217231973">&amp;Vrátiť späť odstránenie</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="2455981314101692989">Táto webová stránka zakázala automatické dopĺňanie tohto formulára.</translation>
<translation id="2479410451996844060">Neplatná webová adresa vyhľadávania.</translation>
+<translation id="2491120439723279231">Certifikát servera obsahuje chyby.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2498091847651709837">Naskenovať novú kartu</translation>
<translation id="2556876185419854533">&amp;Vrátiť späť úpravu</translation>
-<translation id="2581221116934462656">Chcete, aby aplikácia <ph name="PRODUCT_NAME"/> na tomto webe nabudúce ponúkla možnosť prekladu stránok v jazyku <ph name="LANGUAGE_NAME"/>?</translation>
+<translation id="2581221116934462656">Chcete, aby aplikácia <ph name="PRODUCT_NAME" /> na tomto webe nabudúce ponúkla možnosť prekladu stránok v jazyku <ph name="LANGUAGE_NAME" />?</translation>
<translation id="2587841377698384444">Identifikátor priečinka API:</translation>
<translation id="2597378329261239068">Tento dokument je chránený heslom. Zadajte heslo.</translation>
+<translation id="2625385379895617796">Vaše hodiny idú dopredu</translation>
<translation id="2639739919103226564">Stav:</translation>
+<translation id="2653659639078652383">Odoslať</translation>
<translation id="2704283930420550640">Hodnota nezodpovedá formátu.</translation>
<translation id="2721148159707890343">Žiadosť bola úspešná</translation>
+<translation id="2728127805433021124">Certifikát servera je podpísaný pomocou slabého podpisového algoritmu.</translation>
<translation id="2774256287122201187">Môžete pokračovať. Ak budete pokračovať na stránku, toto upozornenie sa zobrazí až o päť minút.</translation>
<translation id="277499241957683684">Chýbajúci záznam zariadenia</translation>
<translation id="2835170189407361413">Vymazať formulár</translation>
-<translation id="2855922900409897335">Overenie karty <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Overenie karty <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Tento server nedokázal potvrdiť, že ide o doménu <ph name="DOMAIN" />, pretože vypršala platnosť bezpečnostného certifikátu. Môže to byť následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útočníkom. Hodiny vášho počítača sú momentálne nastavené na <ph name="CURRENT_TIME" />. Je tento čas správny? Ak nie, opravte čas na hodinách systému a potom obnovte túto stránku.</translation>
+<translation id="2922350208395188000">Certifikát servera sa nedá overiť.</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="2958431318199492670">Konfigurácia siete nie je v súlade so štandardom ONC. Niektoré časti konfigurácie sa nemusia importovať.</translation>
<translation id="2972581237482394796">&amp;Dopredu</translation>
-<translation id="3010559122411665027">Položka zoznamu „<ph name="ENTRY_INDEX"/>“: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Položka zoznamu „<ph name="ENTRY_INDEX" />“: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Chybný typ pravidla</translation>
<translation id="3105172416063519923">Identifikátor obsahu:</translation>
<translation id="3145945101586104090">Odpoveď sa nepodarilo dekódovať</translation>
@@ -80,32 +99,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ostrov</translation>
<translation id="3219579145727097045">Zadajte dátum vypršania platnosti a štvormiestny kód CVC z prednej strany svojej karty</translation>
-<translation id="3228969707346345236">Prekladanie zlyhalo, pretože stránka už je v jazyku: <ph name="LANGUAGE"/></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="3228969707346345236">Prekladanie zlyhalo, pretože stránka už je v jazyku: <ph name="LANGUAGE" /></translation>
<translation id="3270847123878663523">&amp;Vrátiť späť zmenu poradia</translation>
+<translation id="3286538390144397061">Reštartovať</translation>
<translation id="333371639341676808">Zakázať tejto stránke otvárať ďalšie dialógové okná.</translation>
-<translation id="3369366829301677151">Aktualizácia a overenie karty <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">nastavenia</translation>
+<translation id="3369192424181595722">Chyba hodín</translation>
+<translation id="3369366829301677151">Aktualizácia a overenie karty <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Odstránené</translation>
<translation id="3377188786107721145">Chyba analýzy pravidla</translation>
<translation id="3380365263193509176">Neznáma chyba</translation>
<translation id="3380864720620200369">ID klienta:</translation>
<translation id="3427342743765426898">&amp;Znova upraviť</translation>
+<translation id="3435896845095436175">Aktivovať</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Interval načítania:</translation>
+<translation id="3462200631372590220">Skryť rozšírené podrobnosti</translation>
+<translation id="3528171143076753409">Certifikát servera nie je dôveryhodný.</translation>
<translation id="3542684924769048008">Použiť heslo pre:</translation>
<translation id="3583757800736429874">&amp;Znova presunúť</translation>
<translation id="3623476034248543066">Zobraziť hodnotu</translation>
+<translation id="3648607100222897006">Tieto experimentálne funkcie sa môžu kedykoľvek zmeniť, pokaziť alebo zmiznúť. Za dôsledky používania týchto experimentov neručíme. Váš prehliadač sa môže samovoľne vznietiť. Ale teraz vážne. Prehliadač môže odstrániť všetky vaše dáta alebo nečakanými spôsobmi narušiť zabezpečenie či ochranu osobných údajov. Experimenty, ktoré povolíte, budú k dispozícii všetkým používateľom tohto prehliadača. Buďte preto opatrní.</translation>
<translation id="3650584904733503804">Overenie bolo úspešné</translation>
<translation id="370665806235115550">Načítava sa...</translation>
<translation id="3712624925041724820">Vyčerpané licencie</translation>
<translation id="3739623965217189342">Skopírovaný odkaz</translation>
<translation id="375403751935624634">Preklad zlyhal v dôsledku chyby servera.</translation>
<translation id="385051799172605136">Naspäť</translation>
+<translation id="3858027520442213535">Aktualizovať dátum a čas</translation>
<translation id="3884278016824448484">Kolidujúci identifikátor zariadenia</translation>
<translation id="3885155851504623709">Okrsok</translation>
<translation id="3934680773876859118">Načítanie dokumentu PDF zlyhalo</translation>
<translation id="3963721102035795474">Režim čítačky</translation>
<translation id="4030383055268325496">&amp;Vrátiť späť pridanie</translation>
-<translation id="4058922952496707368">Kľúč <ph name="SUBKEY"/>: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">UPOZORNENIE</translation>
+<translation id="4058922952496707368">Kľúč <ph name="SUBKEY" />: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Konfigurácia proxy je nastavená na použitie skriptu PAC webovej adresy, nie pevne daných serverov proxy.</translation>
<translation id="409504436206021213">Nenačítať</translation>
<translation id="4103249731201008433">Sériové číslo zariadenia je neplatné</translation>
@@ -118,40 +147,56 @@
<translation id="4258748452823770588">Chybný podpis</translation>
<translation id="4269787794583293679">(Žiadne používateľské meno)</translation>
<translation id="4300246636397505754">Návrhy rodiča</translation>
-<translation id="4372948949327679948">Očakávaná hodnota <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Článok sa nepodarilo nájsť</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="4394049700291259645">Zakázať</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="443673843213245140">Použitie servera proxy je zakázané, ale je určená explicitná konfigurácia servera proxy.</translation>
-<translation id="4506176782989081258">Chyba overenia: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Chyba overenia: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chcete adresu odstrániť z prehliadača Chrome?</translation>
<translation id="4594403342090139922">&amp;Vrátiť späť odstránenie</translation>
<translation id="4607653538520819196">Šetrič dát nedokáže túto stránku smerovať cez proxy server</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="4726672564094551039">Znova načítať pravidlá</translation>
+<translation id="4728558894243024398">Platforma</translation>
+<translation id="4771973620359291008">Vyskytla sa neznáma chyba.</translation>
<translation id="4800132727771399293">Skontrolujte dátum vypršania platnosti aj kód CVC a skúste to znova</translation>
<translation id="4813512666221746211">Chyba siete</translation>
+<translation id="4816492930507672669">Prispôsobiť stránke</translation>
<translation id="4850886885716139402">Zobraziť</translation>
-<translation id="4923417429809017348">Táto stránka bola preložená z neznámeho jazyka do jazyka <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Táto stránka bola preložená z neznámeho jazyka do jazyka <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Musí byť určená.</translation>
<translation id="4968547170521245791">Nie je možné smerovať cez proxy server</translation>
-<translation id="498957508165411911">Preložiť z jazyka <ph name="ORIGINAL_LANGUAGE"/> do jazyka <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Preložiť z jazyka <ph name="ORIGINAL_LANGUAGE" /> do jazyka <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Zlý stav záložného ukladacieho priestoru</translation>
<translation id="5031870354684148875">O službe Prekladač Google</translation>
+<translation id="5045550434625856497">Nesprávne heslo</translation>
+<translation id="5087286274860437796">Certifikát servera je momentálne neplatný</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="5145883236150621069">V odpovedi na pravidlo sa nachádza kód chyby</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="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="5199729219167945352">Experimenty</translation>
+<translation id="5251803541071282808">Cloud</translation>
<translation id="5295309862264981122">Potvrdiť navigáciu</translation>
<translation id="5299298092464848405">Pri analýze pravidla sa vyskytla chyba</translation>
+<translation id="5316812925700871227">Otočiť proti smeru hodinových ručičiek</translation>
<translation id="5317780077021120954">Uložiť</translation>
<translation id="536296301121032821">Nastavenia pravidla sa nepodarilo uložiť</translation>
-<translation id="5439770059721715174">Pri overení schémy sa vyskytla chyba na mieste <ph name="ERROR_PATH"/>: <ph name="ERROR"/></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="5439770059721715174">Pri overení schémy sa vyskytla chyba na mieste <ph name="ERROR_PATH" />: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Chybná časová pečiatka pravidla</translation>
<translation id="5470861586879999274">&amp;Znova upraviť</translation>
<translation id="5509780412636533143">Spravované záložky</translation>
<translation id="5523118979700054094">Názov pravidla</translation>
<translation id="552553974213252141">Bol text vyňatý správne?</translation>
<translation id="5540224163453853">Požadovaný článok sa nepodarilo nájsť.</translation>
+<translation id="5556459405103347317">Obnoviť</translation>
<translation id="5565735124758917034">Aktívne</translation>
<translation id="560412284261940334">Správa nie je podporovaná</translation>
<translation id="5629630648637658800">Nastavenia pravidla sa nepodarilo načítať</translation>
@@ -159,46 +204,56 @@
<translation id="5720705177508910913">Aktuálny používateľ</translation>
<translation id="5813119285467412249">&amp;Znova pridať</translation>
<translation id="5872918882028971132">Návrhy rodiča</translation>
-<translation id="587701087903783706">Zavrieť zobrazenie vhodné pre mobilné zariadenia</translation>
<translation id="59107663811261420">Služba Google Payments nepodporuje v prípade tohto obchodníka tento typ karty. Vyberte inú kartu.</translation>
+<translation id="5975083100439434680">Oddialiť</translation>
<translation id="5989320800837274978">Nie sú určené pevne dané servery proxy ani skript PAC webovej adresy.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Zatvoriť</translation>
+<translation id="6060685159320643512">Opatrne, tieto experimenty môžu spôsobiť problémy</translation>
+<translation id="6151417162996330722">Obdobie platnosti certifikátu servera je príliš dlhé</translation>
<translation id="6154808779448689242">Vrátený token pravidla sa nezhoduje s aktuálnym tokenom</translation>
<translation id="6165508094623778733">Viac informácií</translation>
<translation id="6259156558325130047">&amp;Znova zmeniť poradie</translation>
-<translation id="6263376278284652872">Záložky domény <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Záložky domény <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Poštový kód</translation>
<translation id="6337534724793800597">Filtrovať pravidlá podľa mena</translation>
+<translation id="6387478394221739770">Máte záujem o skvelé nové funkcie prehliadača Chrome? Vyskúšajte verziu beta na stránke chrome.com/beta.</translation>
+<translation id="6426993025560594914">Na vašej platforme sú k dispozícii všetky experimenty.</translation>
<translation id="6445051938772793705">Krajina</translation>
<translation id="6458467102616083041">Ignorované, pretože predvolený vyhľadávač je podľa pravidla zakázaný.</translation>
<translation id="647261751007945333">Pravidlá zariadenia</translation>
<translation id="6512448926095770873">Odísť z tejto stránky</translation>
<translation id="6529602333819889595">&amp;Znova odstrániť</translation>
<translation id="6550675742724504774">Možnosti</translation>
-<translation id="6597614308054261376">Pokúšate sa prejsť na stránku <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Šetrič dát túto stránku v súčasnosti nedokáže smerovať cez proxy server.</translation>
-<translation id="6628463337424475685">Vyhľadávanie <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Pokúšate sa prejsť na stránku <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Šetrič dát túto stránku v súčasnosti nedokáže smerovať cez proxy server.</translation>
+<translation id="6628463337424475685">Vyhľadávanie <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Toto pravidlo bolo označené ako zastarané.</translation>
<translation id="6646897916597483132">Zadajte štvormiestny kód CVC z prednej strany svojej karty</translation>
+<translation id="674375294223700098">Neznáma chyba spôsobená certifikátom servera.</translation>
<translation id="6753269504797312559">Hodnota pravidla</translation>
<translation id="6831043979455480757">Preložiť</translation>
<translation id="6839929833149231406">Oblasť</translation>
<translation id="6874604403660855544">&amp;Znova pridať</translation>
<translation id="6891596781022320156">Úroveň pravidla nie je podporovaná.</translation>
<translation id="6915804003454593391">Používateľ:</translation>
+<translation id="6957887021205513506">Zdá sa, že certifikát servera je falošný.</translation>
<translation id="6965382102122355670">OK</translation>
<translation id="6965978654500191972">Zariadenie</translation>
<translation id="6970216967273061347">Obvod</translation>
<translation id="6973656660372572881">Určené sú pevne dané servery proxy aj skript PAC webovej adresy.</translation>
<translation id="6980028882292583085">Upozornenie kódu JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Pokúsili ste sa prejsť do domény <ph name="DOMAIN" />, ale server udelil certifikát, ktorého obdobie platnosti je príliš dlhé, a preto nie je dôveryhodný</translation>
<translation id="7087282848513945231">Grófstvo</translation>
-<translation id="7108649287766967076">Preklad do jazyka <ph name="TARGET_LANGUAGE"/> zlyhal.</translation>
+<translation id="7108649287766967076">Preklad do jazyka <ph name="TARGET_LANGUAGE" /> zlyhal.</translation>
<translation id="7139724024395191329">Emirát</translation>
+<translation id="7179921470347911571">Reštartovať teraz</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="7186367841673660872">Táto stránka bola preložená z jazyka<ph name="ORIGINAL_LANGUAGE" />do jazyka<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Na stránke <ph name="SITE_NAME"/> hľadať text <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Na stránke <ph name="SITE_NAME" /> hľadať text <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Súkromné pripojenie k doméne <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> sa nedá nadviazať, pretože dátum a čas (<ph name="DATE_AND_TIME" />) vášho počítača sú nesprávne.</translation>
<translation id="7275334191706090484">Spravované záložky</translation>
<translation id="7298195798382681320">Odporúčané</translation>
<translation id="7334320624316649418">&amp;Znova zmeniť poradie</translation>
@@ -209,31 +264,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Povinné</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="7568593326407688803">Táto stránka je v jazyku<ph name="ORIGINAL_LANGUAGE"/>Chceli by ste ju preložiť?</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="7568593326407688803">Táto stránka je v jazyku<ph name="ORIGINAL_LANGUAGE" />Chceli by ste ju preložiť?</translation>
<translation id="7569952961197462199">Chcete kreditnú kartu odstrániť z prehliadača Chrome?</translation>
-<translation id="7600965453749440009">Nikdy neprekladať jazyk <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Hodnota (<ph name="VALUE"/>) presahuje povolený rozsah.</translation>
+<translation id="7592362899630581445">Certifikát servera porušuje obmedzenia názvov.</translation>
+<translation id="7600965453749440009">Nikdy neprekladať jazyk <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Hodnota (<ph name="VALUE" />) presahuje povolený rozsah.</translation>
+<translation id="7674629440242451245">Máte záujem o skvelé nové funkcie prehliadača Chrome? Vyskúšajte verziu pre vývojárov na stránke chrome.com/dev.</translation>
<translation id="7752995774971033316">Nespravované</translation>
+<translation id="7761701407923456692">Certifikát servera sa nezhoduje s webovou adresou.</translation>
<translation id="777702478322588152">Prefektúra</translation>
<translation id="7791543448312431591">Pridať</translation>
<translation id="7805768142964895445">Stav</translation>
<translation id="7813600968533626083">Chcete návrh odstrániť z prehliadača Chrome?</translation>
<translation id="7887683347370398519">Skontrolujte svoj kód CVC a skúste to znova</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Certifikát servera ešte nie je platný.</translation>
<translation id="7956713633345437162">Záložky v mobile</translation>
<translation id="7961015016161918242">Nikdy</translation>
<translation id="7977590112176369853">&lt;zadajte dotaz&gt;</translation>
-<translation id="7983301409776629893">Vždy preložiť jazyk <ph name="ORIGINAL_LANGUAGE"/> do jazyka <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Vždy preložiť jazyk <ph name="ORIGINAL_LANGUAGE" /> do jazyka <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Záložky plochy</translation>
<translation id="7995512525968007366">Nie je upresnené</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="8003882219468422867">Prekonanie na podnikovej úrovni</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="8088680233425245692">Článok sa nepodarilo zobraziť.</translation>
<translation id="8091372947890762290">Aktivácia čaká na server</translation>
<translation id="8194797478851900357">&amp;Vrátiť späť presunutie</translation>
-<translation id="8201077131113104583">Neplatná webová adresa aktualizácie pre rozšírenie s ID <ph name="EXTENSION_ID"/>.</translation>
+<translation id="8201077131113104583">Neplatná webová adresa aktualizácie pre rozšírenie s ID <ph name="EXTENSION_ID" />.</translation>
<translation id="8208216423136871611">Neuložiť</translation>
<translation id="8218327578424803826">Pridelená poloha:</translation>
<translation id="8249320324621329438">Naposledy načítané:</translation>
+<translation id="8294431847097064396">Zdroj</translation>
<translation id="8308427013383895095">Preklad zlyhal v dôsledku problému so sieťovým pripojením.</translation>
<translation id="8311778656528046050">Naozaj chcete znova načítať túto stránku?</translation>
<translation id="8349305172487531364">Panel so záložkami</translation>
@@ -242,25 +304,40 @@
<translation id="8488350697529856933">Platí pre</translation>
<translation id="8530504477309582336">Služba Google Payments nepodporuje tento typ karty. Vyberte inú kartu.</translation>
<translation id="8553075262323480129">Prekladanie zlyhalo, pretože sa nepodarilo určiť jazyk stránky.</translation>
-<translation id="8571890674111243710">Prebieha preklad stránky do jazyka: <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Súkromné pripojenie k doméne <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> sa nedá nadviazať, pretože dátum a čas (<ph name="DATE_AND_TIME" />) vášho zariadenia sú nesprávne.</translation>
+<translation id="8571890674111243710">Prebieha preklad stránky do jazyka: <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Obnoviť predvolené nastavenia všetkých experimentov</translation>
<translation id="8713130696108419660">Nesprávny počiatočný podpis</translation>
<translation id="8725066075913043281">Skúsiť znova</translation>
+<translation id="8738058698779197622">Ak chcete nadviazať zabezpečené pripojenie, vaše hodiny musia byť nastavené správne. Je to preto, že certifikáty, ktoré webové stránky používajú na vlastnú identifikáciu, sú platné iba určitý čas. Keďže nie sú hodiny vášho zariadenia nastavené správne, Chromium nemôže tieto certifikáty overiť.</translation>
<translation id="8790007591277257123">&amp;Znova vymazať</translation>
<translation id="8804164990146287819">Pravidlá ochrany osobných údajov</translation>
+<translation id="8820817407110198400">Záložky</translation>
<translation id="8824019021993735287">Prehliadaču Chrome sa nepodarilo overiť vašu kartu. Skúste to znova neskôr.</translation>
<translation id="8834246243508017242">Povoliť automatické dopĺňanie pomocou Kontaktov…</translation>
<translation id="883848425547221593">Iné záložky</translation>
+<translation id="884923133447025588">Nenašiel sa žiadny mechanizmus rušenia certifikátov.</translation>
<translation id="8866481888320382733">Pri analýze nastavení pravidla sa vyskytla chyba</translation>
<translation id="8876793034577346603">Konfiguráciu siete sa nepodarilo analyzovať.</translation>
<translation id="8891727572606052622">Neplatný režim proxy.</translation>
-<translation id="8940229512486821554">Spustiť príkaz rozšírenia <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Je nám ľúto, ale tento experiment nie je na vašej platforme k dispozícii.</translation>
+<translation id="8903921497873541725">Priblížiť</translation>
+<translation id="8932102934695377596">Vaše hodiny idú pozadu</translation>
+<translation id="8940229512486821554">Spustiť príkaz rozšírenia <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Platnosť certifikátu servera vypršala.</translation>
<translation id="8988760548304185580">Zadajte dátum vypršania platnosti a trojmiestny kód CVC zo zadnej strany svojej karty</translation>
-<translation id="9020542370529661692">Táto stránka bola preložená do jazyka <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Príznaky, ktoré platia v celom systéme, môže nastaviť iba vlastník: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Táto stránka bola preložená do jazyka <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Pokúšate sa otvoriť doménu <ph name="DOMAIN" />, ale server predložil neplatný certifikát.</translation>
<translation id="9125941078353557812">Zadajte trojmiestny kód CVC zo zadnej strany svojej karty</translation>
<translation id="9137013805542155359">Zobraziť originál</translation>
<translation id="9148507642005240123">&amp;Vrátiť späť úpravu</translation>
<translation id="9154176715500758432">Zostať na tejto stránke</translation>
<translation id="9170848237812810038">&amp;Naspäť</translation>
+<translation id="917450738466192189">Certifikát servera je neplatný.</translation>
+<translation id="9187827965378254003">Zdá sa, že momentálne nie sú k dispozícii žiadne experimenty.</translation>
<translation id="9207861905230894330">Článok sa nepodarilo pridať.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">VYMAZAŤ FORMULÁR</translation>
+<translation id="988159990683914416">Zostavenie pre vývojárov</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_sl.xtb b/chromium/components/strings/components_strings_sl.xtb
index bfeff88ee3d..0fd5f6d9069 100644
--- a/chromium/components/strings/components_strings_sl.xtb
+++ b/chromium/components/strings/components_strings_sl.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="sl">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sl">
+<translation id="1032854598605920125">Sukanje v smeri urnega kazalca</translation>
<translation id="1055184225775184556">&amp;Razveljavi dodajanje</translation>
<translation id="106701514854093668">Zaznamki namizja</translation>
-<translation id="1103523840287552314">Vedno prevedi ta jezik: <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Prilagoditev prikaza širini</translation>
+<translation id="1103523840287552314">Vedno prevedi ta jezik: <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Razveljavi razvrstitev</translation>
<translation id="111844081046043029">Ali ste prepričani, da želite zapustiti to stran?</translation>
<translation id="112840717907525620">Predpomnilnik pravilnika ustrezen</translation>
<translation id="1132774398110320017">Nastavitve samodejnega izpolnjevanja v Chromu …</translation>
-<translation id="1152921474424827756">Odprite <ph name="BEGIN_LINK"/>predpomnjeno kopijo<ph name="END_LINK"/> strani na naslovu <ph name="URL"/></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="1152921474424827756">Odprite <ph name="BEGIN_LINK" />predpomnjeno kopijo<ph name="END_LINK" /> strani na naslovu <ph name="URL" /></translation>
+<translation id="121201262018556460">Poskusili ste dostopati do domene <ph name="DOMAIN" />, vendar ima strežnik potrdilo s šibkim ključem. Napadalec je morda dešifriral zasebni ključ in strežnik morda ni tisti, ki ste ga pričakovali (morda komunicirate z napadalcem).</translation>
<translation id="1227224963052638717">Neznan pravilnik</translation>
<translation id="1227633850867390598">Skrij vrednost</translation>
<translation id="1228893227497259893">Napačni identifikator subjekta</translation>
@@ -14,65 +20,78 @@
<translation id="1339601241726513588">Domena za prijavo:</translation>
<translation id="1344588688991793829">Nastavitve samodejnega izpolnjevanja v Chromiumu …</translation>
<translation id="1426410128494586442">Da</translation>
+<translation id="1430915738399379752">Natisni</translation>
<translation id="1455235771979731432">Težava pri preverjanju kartice. Preverite internetno povezavo in poskusite znova.</translation>
<translation id="1491151370853475546">Znova naloži stran</translation>
<translation id="1549470594296187301">Če želite uporabljati to funkcijo, mora biti omogočen JavaScript.</translation>
-<translation id="1639239467298939599">Nalaganje</translation>
<translation id="1640180200866533862">Uporabniški pravilniki</translation>
<translation id="1644184664548287040">Omrežna konfiguracija ni veljavna in je ni mogoče uvoziti.</translation>
-<translation id="1693754753824026215">Na strani na naslovu <ph name="SITE"/> je navedeno:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo včeraj. Razlog za to je lahko napačna konfiguracija ali napadalčevo prestrezanje povezave. Ura vašega računalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? Če ni, pravilno nastavite sistemsko uro in nato osvežite stran.}one{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevom. Razlog za to je lahko napačna konfiguracija ali napadalčevo prestrezanje povezave. Ura vašega računalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? Če ni, pravilno nastavite sistemsko uro in nato osvežite stran.}two{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevoma. Razlog za to je lahko napačna konfiguracija ali napadalčevo prestrezanje povezave. Ura vašega računalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? Če ni, pravilno nastavite sistemsko uro in nato osvežite stran.}few{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevi. Razlog za to je lahko napačna konfiguracija ali napadalčevo prestrezanje povezave. Ura vašega računalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? Če ni, pravilno nastavite sistemsko uro in nato osvežite stran.}other{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevi. Razlog za to je lahko napačna konfiguracija ali napadalčevo prestrezanje povezave. Ura vašega računalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? Če ni, pravilno nastavite sistemsko uro in nato osvežite stran.}}</translation>
+<translation id="168841957122794586">Potrdilo strežnika vsebuje šibek šifrirni ključ.</translation>
+<translation id="1693754753824026215">Na strani na naslovu <ph name="SITE" /> je navedeno:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; operacijski sistem vaše naprave ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napačna konfiguracija ali napadalčevo prestrezanje povezave.</translation>
<translation id="1821930232296380041">Neveljavna zahteva ali parametri zahteve</translation>
-<translation id="1853748787962613237">Članka ni bilo mogoče prikazati.</translation>
<translation id="1871208020102129563">Proxy je nastavljen na uporabo stalnih strežnikov proxy, ne na URL skripta .pac.</translation>
-<translation id="1875753206475436906">vrsta hevristike: <ph name="HEURISTIC_TYPE"/>
- vrsta strežnika: <ph name="SERVER_TYPE"/>
- podpis polja: <ph name="FIELD_SIGNATURE"/>
- podpis obrazca: <ph name="FORM_SIGNATURE"/>
- id poskusa: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Pojdite na <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Zaznamki domene <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Pojdite na <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Zaznamki domene <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Napaka pri serializaciji</translation>
+<translation id="1974060860693918893">Dodatno</translation>
<translation id="2025186561304664664">Strežnik proxy je nastavljen na samodejno konfiguriranje.</translation>
<translation id="2025623846716345241">Potrditev vnovičnega nalaganja</translation>
-<translation id="2030481566774242610">Ali ste mislili <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Ali ste mislili <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Poštna številka</translation>
<translation id="20817612488360358">Za uporabo so nastavljene sistemske nastavitve strežnika proxy, vendar je navedena tudi izrecna konfiguracija proxyja.</translation>
<translation id="2094505752054353250">Neujemanje domen</translation>
<translation id="2096368010154057602">Departma</translation>
<translation id="2113977810652731515">Kartica</translation>
-<translation id="2114841414352855701">Prezrto, ker je to preglasil pravilnik <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Prezrto, ker je to preglasil pravilnik <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Tehnologija Native Client</translation>
<translation id="213826338245044447">Zaznamki mobilne naprave</translation>
+<translation id="2171101176734966184">Poskusili ste dostopati do domene <ph name="DOMAIN" />, vendar ima strežnik potrdilo, podpisano s šibkim podpisnim algoritmom. To pomeni, da so varnostne poverilnice, ki jih je poslal strežnik, morda ponarejene in strežnik morda ni tisti, ki ga pričakujete (morda komunicirate z napadalcem).</translation>
<translation id="2181821976797666341">Pravilniki</translation>
<translation id="2212735316055980242">Pravilnika ni mogoče najti</translation>
<translation id="2213606439339815911">Prenos vnosov ...</translation>
<translation id="225207911366869382">Vrednost za ta pravilnik je zastarela.</translation>
<translation id="2262243747453050782">Napaka HTTP</translation>
-<translation id="2270192940992995399">Članka ni bilo mogoče najti.</translation>
-<translation id="2328300916057834155">Neveljaveni zaznamek na indeksu <ph name="ENTRY_INDEX"/> je bil prezrt</translation>
+<translation id="2282872951544483773">Preizkusi, ki niso na voljo</translation>
+<translation id="229702904922032456">Korensko ali vmesno potrdilo je poteklo.</translation>
+<translation id="2328300916057834155">Neveljaveni zaznamek na indeksu <ph name="ENTRY_INDEX" /> je bil prezrt</translation>
<translation id="2354001756790975382">Drugi zaznamki</translation>
<translation id="2359808026110333948">Nadaljuj</translation>
<translation id="2367567093518048410">Raven</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="2396249848217231973">&amp;Razveljavi izbris</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="2455981314101692989">Spletna stran je onemogočila samodejno izpolnjevanje za ta obrazec.</translation>
<translation id="2479410451996844060">Neveljaven URL iskanja.</translation>
+<translation id="2491120439723279231">V potrdilu strežnika so napake.</translation>
<translation id="2495083838625180221">Razčlenjevalnik za JSON</translation>
<translation id="2498091847651709837">Optično branje nove kartice</translation>
<translation id="2556876185419854533">&amp;Razveljavi urejanje</translation>
-<translation id="2581221116934462656">Želite, da <ph name="PRODUCT_NAME"/> naslednjič ponudi prevajanje strani v jeziku <ph name="LANGUAGE_NAME"/> na tem spletnem mestu?</translation>
+<translation id="2581221116934462656">Želite, da <ph name="PRODUCT_NAME" /> naslednjič ponudi prevajanje strani v jeziku <ph name="LANGUAGE_NAME" /> na tem spletnem mestu?</translation>
<translation id="2587841377698384444">ID API-ja imenika:</translation>
<translation id="2597378329261239068">Dokument je zaščiten z geslom. Vnesite geslo.</translation>
+<translation id="2625385379895617796">Ura prehiteva</translation>
<translation id="2639739919103226564">Stanje:</translation>
+<translation id="2653659639078652383">Pošlji</translation>
<translation id="2704283930420550640">Vrednost se ne ujema z obliko.</translation>
<translation id="2721148159707890343">Zahteva je uspela</translation>
+<translation id="2728127805433021124">Strežnikovo potrdilo je podpisano s šibkim podpisnim algoritmom.</translation>
<translation id="2774256287122201187">Lahko nadaljujete. Če nadaljujete na stran, to opozorilo ne bo prikazano naslednjih pet minut.</translation>
<translation id="277499241957683684">Manjka zapis o napravi</translation>
<translation id="2835170189407361413">Počisti obrazec</translation>
-<translation id="2855922900409897335">Preverjanje kartice <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Preverjanje kartice <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo. Razlog za to je lahko napačna konfiguracija ali napadalčevo prestrezanje povezave. Ura v računalniku je trenutno nastavljena na <ph name="CURRENT_TIME" />. Je to pravilno? Če ni, popravite uro v sistemu in osvežite stran.
+</translation>
+<translation id="2922350208395188000">Potrdila strežnika ni mogoče preveriti.</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="2958431318199492670">Omrežna konfiguracija ne ustreza standardu ONC. Deli konfiguracije morda niso bili uvoženi.</translation>
<translation id="2972581237482394796">&amp;Uveljavi</translation>
-<translation id="3010559122411665027">Vnos na sznamu »<ph name="ENTRY_INDEX"/>«: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Vnos na sznamu »<ph name="ENTRY_INDEX" />«: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Napačna vrsta pravilnika</translation>
<translation id="3105172416063519923">ID sredstva:</translation>
<translation id="3145945101586104090">Dekodiranje odziva ni uspelo</translation>
@@ -80,32 +99,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Otok</translation>
<translation id="3219579145727097045">Vnesite datum poteka in štirimestno kodo CVC na sprednji strani kartice</translation>
-<translation id="3228969707346345236">Prevod ni uspel, ker je stran že v jeziku <ph name="LANGUAGE"/></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="3228969707346345236">Prevod ni uspel, ker je stran že v jeziku <ph name="LANGUAGE" /></translation>
<translation id="3270847123878663523">&amp;Razveljavi razvrstitev</translation>
+<translation id="3286538390144397061">Znova zaženi</translation>
<translation id="333371639341676808">Tej strani preprečite, da bi ustvarila dodatna pogovorna okna.</translation>
-<translation id="3369366829301677151">Posodobitev in preverjanje kartice <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">nastavitve</translation>
+<translation id="3369192424181595722">Napaka ure</translation>
+<translation id="3369366829301677151">Posodobitev in preverjanje kartice <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Nepripravljen</translation>
<translation id="3377188786107721145">Napaka pri razčlenjevanju pravilnika</translation>
<translation id="3380365263193509176">Neznana napaka</translation>
<translation id="3380864720620200369">ID odjemalca:</translation>
<translation id="3427342743765426898">&amp;Uveljavi urejanje</translation>
+<translation id="3435896845095436175">Omogoči</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Interval prejemanja:</translation>
+<translation id="3462200631372590220">Skrij podrobnosti</translation>
+<translation id="3528171143076753409">Potrdilo strežnika ni zaupanja vredno.</translation>
<translation id="3542684924769048008">Uporaba gesla za:</translation>
<translation id="3583757800736429874">&amp;Uveljavi premik</translation>
<translation id="3623476034248543066">Pokaži vrednost</translation>
+<translation id="3648607100222897006">Te poskusne funkcije se lahko kadar koli spremenijo, odpovedo ali izginejo. Ne dajemo nikakršnih jamstev o tem, kaj se lahko zgodi, če omogočite katerega od teh poskusov, vaš brskalnik pa lahko celo spontano zagori. Šalo na stran, vaš brskalnik lahko izbriše vse vaše podatke ali pa sta lahko varnost in zasebnost ogrožena na nepričakovane načine. Vsi poskusi, ki jih omogočite vi, bodo omogočeni za vse uporabnike tega brskalnika. Nadaljujte previdno.</translation>
<translation id="3650584904733503804">Preverjanje veljavnosti uspešno</translation>
<translation id="370665806235115550">Nalagam ...</translation>
<translation id="3712624925041724820">Ni dovolj licenc</translation>
<translation id="3739623965217189342">Povezava, ki ste jo kopirali</translation>
<translation id="375403751935624634">Prevajanje ni uspelo zaradi napake strežnika.</translation>
<translation id="385051799172605136">Nazaj</translation>
+<translation id="3858027520442213535">Posodobi datum in uro</translation>
<translation id="3884278016824448484">Identifikator naprave je v sporu</translation>
<translation id="3885155851504623709">Okrožje</translation>
<translation id="3934680773876859118">Dokumenta PDF ni bilo mogoče naložiti</translation>
<translation id="3963721102035795474">Način bralnika</translation>
<translation id="4030383055268325496">&amp;Razveljavi dodajanje</translation>
-<translation id="4058922952496707368">Ključ »<ph name="SUBKEY"/>«: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">OPOZORILO</translation>
+<translation id="4058922952496707368">Ključ »<ph name="SUBKEY" />«: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Konfiguracija strežnika proxy je nastavljena na uporabo URL-ja skripta .pac, ne na stalne strežnike proxy.</translation>
<translation id="409504436206021213">Ne naloži znova</translation>
<translation id="4103249731201008433">Neveljavna serijska številka naprave</translation>
@@ -118,40 +147,56 @@
<translation id="4258748452823770588">Napačen podpis</translation>
<translation id="4269787794583293679">(Ni uporabniškega imena)</translation>
<translation id="4300246636397505754">Predlogi staršev</translation>
-<translation id="4372948949327679948">Pričakovana vrednost je vrste <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Članka ni bilo mogoče najti</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="4394049700291259645">Onemogoči</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="443673843213245140">Uporaba strežnika proxy je onemogočena, vendar je njegova konfiguracija izrecno določena.</translation>
-<translation id="4506176782989081258">Napaka pri preverjanju veljavnosti: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Napaka pri preverjanju veljavnosti: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Želite odstraniti naslov iz Chroma?</translation>
<translation id="4594403342090139922">&amp;Razveljavi izbris</translation>
<translation id="4607653538520819196">Te strani ni mogoče prenesti prek strežnika proxy za varčevanje s podatki.</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="4726672564094551039">Znova naloži pravilnike</translation>
+<translation id="4728558894243024398">Okolje</translation>
+<translation id="4771973620359291008">Prišlo je do neznane napake.</translation>
<translation id="4800132727771399293">Preverite datum poteka in številko CVC ter poskusite znova</translation>
<translation id="4813512666221746211">Napaka v omrežju</translation>
+<translation id="4816492930507672669">Prilagodi strani</translation>
<translation id="4850886885716139402">Pogled</translation>
-<translation id="4923417429809017348">Stran je bila iz neznanega jezika prevedena v jezik »<ph name="LANGUAGE_LANGUAGE"/>«</translation>
+<translation id="4923417429809017348">Stran je bila iz neznanega jezika prevedena v jezik »<ph name="LANGUAGE_LANGUAGE" />«</translation>
<translation id="4926049483395192435">Vrednost mora biti določena.</translation>
<translation id="4968547170521245791">Prenos prek strežnika proxy ni mogoč</translation>
-<translation id="498957508165411911">Želite prevesti iz jezika <ph name="ORIGINAL_LANGUAGE"/> v jezik <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Želite prevesti iz jezika <ph name="ORIGINAL_LANGUAGE" /> v jezik <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Neprimerno stanje rezervne shrambe</translation>
<translation id="5031870354684148875">Google Prevajalnik – vizitka</translation>
+<translation id="5045550434625856497">Napačno geslo</translation>
+<translation id="5087286274860437796">Potrdilo strežnika trenutno ni veljavno.</translation>
<translation id="5089810972385038852">Zvezna država</translation>
+<translation id="5094747076828555589">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; Chromium ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napačna konfiguracija ali napadalčevo prestrezanje povezave.</translation>
<translation id="5095208057601539847">Provinca</translation>
<translation id="5145883236150621069">Koda napake v odzivu pravilnika</translation>
<translation id="5172758083709347301">Računalnik</translation>
-<translation id="5179510805599951267">Ni v <ph name="ORIGINAL_LANGUAGE"/>? Obvestite nas o tej napaki</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="5199729219167945352">Poskusi</translation>
+<translation id="5251803541071282808">Oblak</translation>
<translation id="5295309862264981122">Potrditev krmarjenja</translation>
<translation id="5299298092464848405">Napaka pri razčlenjevanju pravilnika</translation>
+<translation id="5316812925700871227">Sukanje v nasprotni smeri urnega kazalca</translation>
<translation id="5317780077021120954">Shrani</translation>
<translation id="536296301121032821">Nastavitev pravilnika ni bilo mogoče shraniti</translation>
-<translation id="5439770059721715174">Napaka preverjanja sheme pri »<ph name="ERROR_PATH"/>«: <ph name="ERROR"/></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="5439770059721715174">Napaka preverjanja sheme pri »<ph name="ERROR_PATH" />«: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Napačen časovni žig pravilnika</translation>
<translation id="5470861586879999274">&amp;Uveljavi urejanje</translation>
<translation id="5509780412636533143">Upravljani zaznamki</translation>
<translation id="5523118979700054094">Ime pravilnika</translation>
<translation id="552553974213252141">Ali je bilo besedilo pravilno izvlečeno?</translation>
<translation id="5540224163453853">Zahtevanega članka ni bilo mogoče najti.</translation>
+<translation id="5556459405103347317">Ponovno naloži</translation>
<translation id="5565735124758917034">Aktivno</translation>
<translation id="560412284261940334">Upravljanje ni podprto</translation>
<translation id="5629630648637658800">Nastavitev pravilnika ni bilo mogoče naložiti</translation>
@@ -159,46 +204,56 @@
<translation id="5720705177508910913">Trenutni uporabnik</translation>
<translation id="5813119285467412249">&amp;Uveljavi dodajanje</translation>
<translation id="5872918882028971132">Predlogi staršev</translation>
-<translation id="587701087903783706">Zapri pogled, prilagojen mobilnim napravam</translation>
<translation id="59107663811261420">Ta vrsta kartice ni podprta v storitvi Google Payments pri tem trgovcu. Izberite drugo kartico.</translation>
+<translation id="5975083100439434680">Pomanjšaj</translation>
<translation id="5989320800837274978">Določeni niso ne stalni strežniki proxy ne URL skripta .pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Zapri</translation>
+<translation id="6060685159320643512">Previdno, ti poskusi lahko škodujejo</translation>
+<translation id="6151417162996330722">Potrdilo strežnika ima predolgo obdobje veljavnosti.</translation>
<translation id="6154808779448689242">Vrnjen žeton pravilnika se ne ujema s trenutnim žetonom</translation>
<translation id="6165508094623778733">Več o tem</translation>
<translation id="6259156558325130047">&amp;Uveljavi razvrstitev</translation>
-<translation id="6263376278284652872">Zaznamki <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Zaznamki <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Poštna številka</translation>
<translation id="6337534724793800597">Filtriraj pravilnike po imenu</translation>
+<translation id="6387478394221739770">Vas zanimajo super nove funkcije Chroma? Preskusite naš kanal za različice beta na chrome.com/beta.</translation>
+<translation id="6426993025560594914">V vašem okolju so na voljo vsi preizkusi.</translation>
<translation id="6445051938772793705">Država</translation>
<translation id="6458467102616083041">Prezrto, ker je pravilnik onemogočil privzeto iskanje.</translation>
<translation id="647261751007945333">Pravilniki za naprave</translation>
<translation id="6512448926095770873">Zapusti to stran</translation>
<translation id="6529602333819889595">&amp;Uveljavi izbris</translation>
<translation id="6550675742724504774">Možnosti</translation>
-<translation id="6597614308054261376">Doseči poskušate <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Te strani trenutno ni mogoče prenesti prek strežnika proxy za varčevanje s podatki.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Iskanje</translation>
+<translation id="6597614308054261376">Doseči poskušate <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Te strani trenutno ni mogoče prenesti prek strežnika proxy za varčevanje s podatki.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Iskanje</translation>
<translation id="6644283850729428850">Ta pravilnik je zastarel.</translation>
<translation id="6646897916597483132">Vnesite štirimestno kodo CVC na sprednji strani kartice</translation>
+<translation id="674375294223700098">Neznana napaka potrdila strežnika.</translation>
<translation id="6753269504797312559">Vrednost pravilnika</translation>
<translation id="6831043979455480757">Prevedi</translation>
<translation id="6839929833149231406">Območje</translation>
<translation id="6874604403660855544">&amp;Uveljavi dodajanje</translation>
<translation id="6891596781022320156">Raven pravilnika ni podprta.</translation>
<translation id="6915804003454593391">Uporabnik:</translation>
+<translation id="6957887021205513506">Potrdilo strežnika je očitno ponaredek.</translation>
<translation id="6965382102122355670">V redu</translation>
<translation id="6965978654500191972">Naprava</translation>
<translation id="6970216967273061347">Okraj</translation>
<translation id="6973656660372572881">Določeni so stalni strežniki proxy in URL skripta .pac.</translation>
<translation id="6980028882292583085">Opozorilo JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Poskusili ste odpreti <ph name="DOMAIN" />, vendar je strežnik uporabil potrdilo, ki ima predolgo obdobje veljavnosti, da bi bilo verodostojno.</translation>
<translation id="7087282848513945231">Okraj</translation>
-<translation id="7108649287766967076">Prevod v jezik <ph name="TARGET_LANGUAGE"/> ni uspel.</translation>
+<translation id="7108649287766967076">Prevod v jezik <ph name="TARGET_LANGUAGE" /> ni uspel.</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7179921470347911571">Znova zaženi</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="7186367841673660872">Ta stran je bila prevedena iz jezika<ph name="ORIGINAL_LANGUAGE" />v jezik<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">V iskalniku <ph name="SITE_NAME"/> poišči <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">V iskalniku <ph name="SITE_NAME" /> poišči <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Zasebne povezave z domeno <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ni mogoče vzpostaviti, ker sta datum in ura (<ph name="DATE_AND_TIME" />) v računalniku nepravilna.</translation>
<translation id="7275334191706090484">Upravljani zaznamki</translation>
<translation id="7298195798382681320">Priporočeni</translation>
<translation id="7334320624316649418">&amp;Uveljavi razvrstitev</translation>
@@ -209,31 +264,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obvezen</translation>
<translation id="7542995811387359312">Samodejno izpolnjevanje podatkov o kreditni kartici je onemogočeno, ker ta obrazec ne uporablja varne povezave.</translation>
-<translation id="7568593326407688803">Ta stran je v jeziku:<ph name="ORIGINAL_LANGUAGE"/>Jo želite prevesti?</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="7568593326407688803">Ta stran je v jeziku:<ph name="ORIGINAL_LANGUAGE" />Jo želite prevesti?</translation>
<translation id="7569952961197462199">Želite odstraniti kreditno kartico iz Chroma?</translation>
-<translation id="7600965453749440009">Nikoli ne prevedi iz jezika: <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Vrednost je zunaj obsega <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Strežnikovo potrdilo krši omejitve imen.</translation>
+<translation id="7600965453749440009">Nikoli ne prevedi iz jezika: <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Vrednost je zunaj obsega <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Vas zanimajo super nove funkcije Chroma? Preskusite naš kanal za razvijalce na chrome.com/dev.</translation>
<translation id="7752995774971033316">Odstranjen iz uporabe</translation>
+<translation id="7761701407923456692">Potrdilo strežnika se ne ujema z URL-jem.</translation>
<translation id="777702478322588152">Prefektura</translation>
<translation id="7791543448312431591">Dodaj</translation>
<translation id="7805768142964895445">Stanje</translation>
<translation id="7813600968533626083">Želite odstraniti predlog obrazca iz Chroma?</translation>
<translation id="7887683347370398519">Preverite CVC in poskusite znova</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Potrdilo strežnika še ni veljavno.</translation>
<translation id="7956713633345437162">Zaznamki mobilne naprave</translation>
<translation id="7961015016161918242">Nikoli</translation>
<translation id="7977590112176369853">&lt;vnesite poizvedbo&gt;</translation>
-<translation id="7983301409776629893">Vedno prevedi iz jezika <ph name="ORIGINAL_LANGUAGE"/> v jezik <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Vedno prevedi iz jezika <ph name="ORIGINAL_LANGUAGE" /> v jezik <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Zaznamki namizja</translation>
<translation id="7995512525968007366">Ni navedeno</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="8003882219468422867">Preglasitev za podjetja</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="8088680233425245692">Članka si ni bilo mogoče ogledati.</translation>
<translation id="8091372947890762290">Čakanje na aktivacijo v strežniku</translation>
<translation id="8194797478851900357">&amp;Razveljavi premik</translation>
-<translation id="8201077131113104583">Neveljaven posodobitveni URL za razširitev z ID-jem »<ph name="EXTENSION_ID"/>«.</translation>
+<translation id="8201077131113104583">Neveljaven posodobitveni URL za razširitev z ID-jem »<ph name="EXTENSION_ID" />«.</translation>
<translation id="8208216423136871611">Ne shrani</translation>
<translation id="8218327578424803826">Dodeljena lokacija:</translation>
<translation id="8249320324621329438">Nazadnje preneseno:</translation>
+<translation id="8294431847097064396">Vir</translation>
<translation id="8308427013383895095">Prevod ni uspel zaradi težave s povezavo omrežja.</translation>
<translation id="8311778656528046050">Ali res želite znova naložiti to stran?</translation>
<translation id="8349305172487531364">Vrstica z zaznamki</translation>
@@ -242,25 +304,40 @@
<translation id="8488350697529856933">Velja za</translation>
<translation id="8530504477309582336">Ta vrsta kartice ni podprta v storitvi Google Payments. Izberite drugo kartico.</translation>
<translation id="8553075262323480129">Prevod ni uspel, ker ni mogoče določiti jezika strani.</translation>
-<translation id="8571890674111243710">Prevajanje strani v jezik <ph name="LANGUAGE"/> ...</translation>
+<translation id="8559762987265718583">Zasebne povezave z domeno <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ni mogoče vzpostaviti, ker sta datum in ura (<ph name="DATE_AND_TIME" />) v napravi nepravilna.</translation>
+<translation id="8571890674111243710">Prevajanje strani v jezik <ph name="LANGUAGE" /> ...</translation>
+<translation id="8647750283161643317">Ponastavi vse na privzete</translation>
<translation id="8713130696108419660">Napačen začetni podpis</translation>
<translation id="8725066075913043281">Poskusite znova</translation>
+<translation id="8738058698779197622">Če želite vzpostaviti varno povezavo, mora biti ura pravilno nastavljena. Potrdila, ki jih uporabljajo spletna mesta za prepoznavanje, namreč veljajo samo določen čas. Ker je ura sistema nepravilna, Chromium teh potrdil ne more preveriti.</translation>
<translation id="8790007591277257123">&amp;Uveljavi izbris</translation>
<translation id="8804164990146287819">Pravilnik o zasebnosti</translation>
+<translation id="8820817407110198400">Zaznamki</translation>
<translation id="8824019021993735287">Trenutno trenutno ni mogel preveriti vaše kartice. Poskusite znova pozneje.</translation>
<translation id="8834246243508017242">Omogoči samodejno izpolnjevanje s stiki …</translation>
<translation id="883848425547221593">Drugi zaznamki</translation>
+<translation id="884923133447025588">Najden ni bil noben mehanizem za preklic.</translation>
<translation id="8866481888320382733">Napaka pri razčlenjevanju nastavitev pravilnika</translation>
<translation id="8876793034577346603">Omrežne konfiguracije ni bilo mogoče razčleniti.</translation>
<translation id="8891727572606052622">Neveljaven način strežnika proxy.</translation>
-<translation id="8940229512486821554">Zaženi <ph name="EXTENSION_NAME"/> ukaz: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Oprostite, ta poskus ni na voljo za vaše okolje.</translation>
+<translation id="8903921497873541725">Povečaj</translation>
+<translation id="8932102934695377596">Ura zaostaja</translation>
+<translation id="8940229512486821554">Zaženi <ph name="EXTENSION_NAME" /> ukaz: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Potrdilo strežnika je poteklo.</translation>
<translation id="8988760548304185580">Vnesite datum poteka in trimestno kodo CVC na hrbtni strani kartice</translation>
-<translation id="9020542370529661692">Ta stran je prevedena v jezik <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Zastavice, ki se uporabijo v celotnem sistemu, lahko nastavi samo lastnik: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Ta stran je prevedena v jezik <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Skušali ste dostopati do domene <ph name="DOMAIN" />, vendar je strežnik predložil neveljavno potrdilo.</translation>
<translation id="9125941078353557812">Vnesite trimestno kodo CVC na hrbtni strani kartice</translation>
<translation id="9137013805542155359">Pokaži izvirno besedilo</translation>
<translation id="9148507642005240123">&amp;Razveljavi urejanje</translation>
<translation id="9154176715500758432">Ostani na tej strani</translation>
<translation id="9170848237812810038">&amp;Razveljavi</translation>
+<translation id="917450738466192189">Potrdilo strežnika ni veljavno.</translation>
+<translation id="9187827965378254003">Videti je, da trenutno ni na voljo poskusov.</translation>
<translation id="9207861905230894330">Članka ni bilo mogoče dodati.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">POČISTI OBRAZEC</translation>
+<translation id="988159990683914416">Različica za razvijalce</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_sr.xtb b/chromium/components/strings/components_strings_sr.xtb
index 3d81bcf1290..392cde2aa6a 100644
--- a/chromium/components/strings/components_strings_sr.xtb
+++ b/chromium/components/strings/components_strings_sr.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="sr">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sr">
+<translation id="1032854598605920125">Окрените у смеру казаљке на сату</translation>
<translation id="1055184225775184556">&amp;Опозови додавање</translation>
<translation id="106701514854093668">Обележивачи на рачунару</translation>
-<translation id="1103523840287552314">Увек преводи <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Уклопите по ширини</translation>
+<translation id="1103523840287552314">Увек преводи <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Опозови промену редоследа</translation>
<translation id="111844081046043029">Желите ли стварно да затворите ову страницу?</translation>
<translation id="112840717907525620">Кеш смерница је у реду</translation>
<translation id="1132774398110320017">Подешавања Chrome аутоматског попуњавања...</translation>
-<translation id="1152921474424827756">Приступите <ph name="BEGIN_LINK"/>кешираној копији<ph name="END_LINK"/> странице <ph name="URL"/></translation>
+<translation id="1150979032973867961">Овај сервер не може да докаже да је <ph name="DOMAIN" />; оперативни систем рачунара нема поверења у његов безбедносни сертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
+<translation id="1152921474424827756">Приступите <ph name="BEGIN_LINK" />кешираној копији<ph name="END_LINK" /> странице <ph name="URL" /></translation>
+<translation id="121201262018556460">Покушали сте да контактирате <ph name="DOMAIN" />, али је сервер послао сертификат који садржи слаб кључ. Могуће је да је нападач открио приватни кључ и да сервер можда није онај који мислите да јесте (можда комуницирате са нападачем).</translation>
<translation id="1227224963052638717">Непознате смернице.</translation>
<translation id="1227633850867390598">Сакриј вредност</translation>
<translation id="1228893227497259893">Погрешан идентификатор ентитета</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Домен уписнице:</translation>
<translation id="1344588688991793829">Подешавања Chromium аутоматског попуњавања...</translation>
<translation id="1426410128494586442">Да</translation>
+<translation id="1430915738399379752">Штампај</translation>
<translation id="1455235771979731432">Дошло је до проблема при верификацији картице. Проверите интернет везу и покушајте поново.</translation>
<translation id="1491151370853475546">Поново учитај ову страницу</translation>
<translation id="1549470594296187301">JavaScript мора да буде омогућен да бисте користили ову функцију.</translation>
-<translation id="1639239467298939599">Учитавање</translation>
<translation id="1640180200866533862">Смернице за кориснике</translation>
<translation id="1644184664548287040">Конфигурација мреже је неважећа и не може да се увезе.</translation>
-<translation id="1693754753824026215">Страница на <ph name="SITE"/> каже:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат је истекао јуче. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ако није, требало би да исправите сат система и да затим освежите ову страницу.}one{Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат је истекао пре # дана. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ако није, требало би да исправите сат система и да затим освежите ову страницу.}few{Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат је истекао пре # дана. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ако није, требало би да исправите сат система и да затим освежите ову страницу.}other{Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат је истекао пре # дана. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ако није, требало би да исправите сат система и да затим освежите ову страницу.}}</translation>
+<translation id="168841957122794586">Сертификат сервера садржи слаб криптографски кључ.</translation>
+<translation id="1693754753824026215">Страница на <ph name="SITE" /> каже:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Овај сервер не може да докаже да је <ph name="DOMAIN" />; оперативни систем уређаја нема поверења у његов безбедносни сертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="1821930232296380041">Неважећи захтев или параметри захтева</translation>
-<translation id="1853748787962613237">Приказивање чланка није успело.</translation>
<translation id="1871208020102129563">Прокси је подешен да користи фиксне прокси сервере, а не URL адресу .pac скрипте.</translation>
-<translation id="1875753206475436906">хеуристички тип: <ph name="HEURISTIC_TYPE"/>
- тип сервера: <ph name="SERVER_TYPE"/>
- потпис у пољу: <ph name="FIELD_SIGNATURE"/>
- потпис на обрасцу: <ph name="FORM_SIGNATURE"/>
- ид експеримента: „<ph name="EXPERIMENT_ID"/>“</translation>
-<translation id="194030505837763158">Идите на <ph name="LINK"/></translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> – обележивачи</translation>
+<translation id="194030505837763158">Идите на <ph name="LINK" /></translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> – обележивачи</translation>
<translation id="1973335181906896915">Грешка при серијализацији</translation>
+<translation id="1974060860693918893">Напредне опције</translation>
<translation id="2025186561304664664">Прокси је подешен да буде аутоматски конфигурисан.</translation>
<translation id="2025623846716345241">Потврда поновног учитавања</translation>
-<translation id="2030481566774242610">Да ли сте мислили <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Да ли сте мислили <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Поштански број</translation>
<translation id="20817612488360358">Подешено је да се користе системска подешавања проксија, али је наведена експлицитна конфигурација проксија.</translation>
<translation id="2094505752054353250">Домени се не подударају</translation>
<translation id="2096368010154057602">Департман</translation>
<translation id="2113977810652731515">Картица</translation>
-<translation id="2114841414352855701">Занемарују се јер су замењене смерницама <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Занемарују се јер су замењене смерницама <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Обележивачи на мобилном уређају</translation>
+<translation id="2171101176734966184">Покушали сте да контактирате <ph name="DOMAIN" />, али сервер је послао сертификат потписан слабим алгоритмом. То значи да би безбедносни акредитиви које је сервер послао могли да буду кривотворени тако да сервер можда није онај који мислите да јесте (можда комуницирате са нападачем).</translation>
<translation id="2181821976797666341">Смернице</translation>
<translation id="2212735316055980242">Смернице нису пронађене</translation>
<translation id="2213606439339815911">Преузимање уноса...</translation>
<translation id="225207911366869382">Ова вредност је застарела за ове смернице.</translation>
<translation id="2262243747453050782">HTTP грешка</translation>
-<translation id="2270192940992995399">Није могуће пронаћи чланак.</translation>
-<translation id="2328300916057834155">Неважећи обележивач је игнорисан у индексу <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Недоступни експерименти</translation>
+<translation id="229702904922032456">Сертификат основног или средњег нивоа је истекао.</translation>
+<translation id="2328300916057834155">Неважећи обележивач је игнорисан у индексу <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Остали обележивачи</translation>
<translation id="2359808026110333948">Настави</translation>
<translation id="2367567093518048410">Ниво</translation>
+<translation id="2384307209577226199">Подразумеване смернице за предузеће</translation>
+<translation id="2386255080630008482">Сертификат сервера је опозван.</translation>
<translation id="2392959068659972793">Прикажи смернице без подешених вредности</translation>
<translation id="2396249848217231973">&amp;Опозови брисање</translation>
+<translation id="2413528052993050574">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат ће можда бити опозван. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="2455981314101692989">Ова веб-страница је онемогућила аутоматско попуњавање за овај образац.</translation>
<translation id="2479410451996844060">Неважећа URL адреса претраге.</translation>
+<translation id="2491120439723279231">Сертификат сервера садржи грешке.</translation>
<translation id="2495083838625180221">Рашчлањивач JSON датотека</translation>
<translation id="2498091847651709837">Скенирајте нову картицу</translation>
<translation id="2556876185419854533">&amp;Опозови измену</translation>
-<translation id="2581221116934462656">Желите ли да вам <ph name="PRODUCT_NAME"/> следећи пут понуди да преведе странице чији је језик <ph name="LANGUAGE_NAME"/> на овом сајту?</translation>
+<translation id="2581221116934462656">Желите ли да вам <ph name="PRODUCT_NAME" /> следећи пут понуди да преведе странице чији је језик <ph name="LANGUAGE_NAME" /> на овом сајту?</translation>
<translation id="2587841377698384444">ИД API-ја за директоријуме:</translation>
<translation id="2597378329261239068">Овај документ је заштићен лозинком. Унесите лозинку.</translation>
+<translation id="2625385379895617796">Сат вам жури</translation>
<translation id="2639739919103226564">Статус:</translation>
+<translation id="2653659639078652383">Пошаљи</translation>
<translation id="2704283930420550640">Вредност се не подудара са форматом.</translation>
<translation id="2721148159707890343">Захтев је успео</translation>
+<translation id="2728127805433021124">Сертификат сервера је потписан слабим алгоритмом.</translation>
<translation id="2774256287122201187">Можете да наставите. Ако наставите до странице, ово упозорење се неће поново појавити у наредних пет минута.</translation>
<translation id="277499241957683684">Недостаје евиденција уређаја</translation>
<translation id="2835170189407361413">Обриши образац</translation>
-<translation id="2855922900409897335">Верификујте <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Верификујте <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат је истекао. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_TIME" />. Да ли вам то делује тачно? Ако не делује, треба да исправите сат система и освежите ову страницу.</translation>
+<translation id="2922350208395188000">Није могуће проверити сертификат сервера.</translation>
+<translation id="2941952326391522266">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат је са домена <ph name="DOMAIN2" />. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="2958431318199492670">Конфигурација мреже није у складу са ONC стандардом. Делови конфигурације не могу да се увезу.</translation>
<translation id="2972581237482394796">&amp;Понови радњу</translation>
-<translation id="3010559122411665027">Унос на листи „<ph name="ENTRY_INDEX"/>“: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Унос на листи „<ph name="ENTRY_INDEX" />“: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Погрешан тип смерница</translation>
<translation id="3105172416063519923">ИД елемента:</translation>
<translation id="3145945101586104090">Декодирање одговора није успело</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Острво</translation>
<translation id="3219579145727097045">Унесите датум истека и четвороцифрени CVC који се налази на предњој страни картице</translation>
-<translation id="3228969707346345236">Превод није успео јер је страница већ на језику <ph name="LANGUAGE"/>.</translation>
+<translation id="3225919329040284222">Сервер је приказао сертификат који се не подудара са уграђеним очекивањима. Та очекивања су обухваћена за одређене веб сајтове са јаким безбедносним мерама како би вас заштитила.</translation>
+<translation id="3228969707346345236">Превод није успео јер је страница већ на језику <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Опозови промену редоследа</translation>
+<translation id="3286538390144397061">Поново покрени одмах</translation>
<translation id="333371639341676808">Спречите ову страницу да прави додатне дијалоге.</translation>
-<translation id="3369366829301677151">Ажурирајте и верификујте <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">подешавања</translation>
+<translation id="3369192424181595722">Грешка на сату</translation>
+<translation id="3369366829301677151">Ажурирајте и верификујте <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Онемогућен је</translation>
<translation id="3377188786107721145">Грешка при рашчлањивању смерница</translation>
<translation id="3380365263193509176">Непозната грешка</translation>
<translation id="3380864720620200369">ИД клијента:</translation>
<translation id="3427342743765426898">&amp;Понови измену</translation>
+<translation id="3435896845095436175">Омогући</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Интервал учитавања:</translation>
+<translation id="3462200631372590220">Сакриј напредно</translation>
+<translation id="3528171143076753409">Сертификат сервера није поуздан.</translation>
<translation id="3542684924769048008">Користи лозинку за:</translation>
<translation id="3583757800736429874">&amp;Понови премештање</translation>
<translation id="3623476034248543066">Прикажи вредност</translation>
+<translation id="3648607100222897006">Ове експерименталне функције у сваком тренутку могу да се промене, нестану или престану да функционишу. Не дајемо никакве гаранције у вези са тим шта може да се деси ако укључите неки од ових експеримената и прегледач вам спонтано експлодира. Шалу на страну, прегледач може да вам избрише све податке и безбедност и приватност може да буде угрожена на неочекиване начине. Сви експерименти које омогућите биће омогућени за све кориснике прегледача. Будите опрезни.</translation>
<translation id="3650584904733503804">Потврда ваљаности је успела</translation>
<translation id="370665806235115550">Учитава се...</translation>
<translation id="3712624925041724820">Нема више лиценци</translation>
<translation id="3739623965217189342">Линк који сте копирали</translation>
<translation id="375403751935624634">Превођење није успело због грешке сервера.</translation>
<translation id="385051799172605136">Назад</translation>
+<translation id="3858027520442213535">Ажурирајте датум и време</translation>
<translation id="3884278016824448484">Неусаглашени идентификатор уређаја</translation>
<translation id="3885155851504623709">Парохија</translation>
<translation id="3934680773876859118">Учитавање PDF документа није успело</translation>
<translation id="3963721102035795474">Режим читаоца</translation>
<translation id="4030383055268325496">&amp;Опозови додавање</translation>
-<translation id="4058922952496707368">Кључ „<ph name="SUBKEY"/>“: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">УПОЗОРЕЊЕ</translation>
+<translation id="4058922952496707368">Кључ „<ph name="SUBKEY" />“: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Конфигурација проксија је подешена да користи URL адресу .pac скрипте, а не фиксне прокси сервере.</translation>
<translation id="409504436206021213">Не учитавај поново</translation>
<translation id="4103249731201008433">Серијски број уређаја је неважећи</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Неисправан потпис</translation>
<translation id="4269787794583293679">(Без корисничког имена)</translation>
<translation id="4300246636397505754">Предлози родитеља</translation>
-<translation id="4372948949327679948">Очекивана вредност je <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Нисмо успели да пронађемо чланак</translation>
+<translation id="4372948949327679948">Очекивана вредност je <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Покушали сте да контактирате <ph name="DOMAIN" />, али је издавач опозвао сертификат који је сервер навео. То значи да никако не треба имати поверења у безбедносне акредитиве које је сервер навео. Могуће је да комуницирате са нападачем.</translation>
+<translation id="4394049700291259645">Онемогући</translation>
+<translation id="4424024547088906515">Овај сервер не може да докаже да је <ph name="DOMAIN" />; Chrome нема поверења у његов безбедносни сертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="443673843213245140">Коришћење проксија је онемогућено, али је наведена експлицитна конфигурација проксија.</translation>
-<translation id="4506176782989081258">Грешка при потврди ваљаности: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Грешка при потврди ваљаности: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Желите ли да уклоните адресу из Chrome-а?</translation>
<translation id="4594403342090139922">&amp;Опозови брисање</translation>
<translation id="4607653538520819196">Уштеда података не може да пренесе ову страницу.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат садржи грешке. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="4726672564094551039">Поново учитај смернице</translation>
+<translation id="4728558894243024398">Платформа</translation>
+<translation id="4771973620359291008">Дошло је до непознате грешке.</translation>
<translation id="4800132727771399293">Проверите датум истека и CVC и покушајте поново</translation>
<translation id="4813512666221746211">Грешка на мрежи</translation>
+<translation id="4816492930507672669">Уклопи у страницу</translation>
<translation id="4850886885716139402">Приказ</translation>
-<translation id="4923417429809017348">Ова страница је преведена са непознатог језика на <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Ова страница је преведена са непознатог језика на <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Мора да буде наведено.</translation>
<translation id="4968547170521245791">Пренос није могућ</translation>
-<translation id="498957508165411911">Желите ли да преведете са језика <ph name="ORIGINAL_LANGUAGE"/> на <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Желите ли да преведете са језика <ph name="ORIGINAL_LANGUAGE" /> на <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Складиште тока података је у лошем стању</translation>
<translation id="5031870354684148875">О Google преводиоцу</translation>
+<translation id="5045550434625856497">Нетачна лозинка</translation>
+<translation id="5087286274860437796">Сертификат сервера тренутно није важећи.</translation>
<translation id="5089810972385038852">Држава</translation>
+<translation id="5094747076828555589">Овај сервер не може да докаже да је <ph name="DOMAIN" />; Chromium нема поверења у његов безбедносни сертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="5095208057601539847">Провинција</translation>
<translation id="5145883236150621069">Кôд грешке је присутан у одговору на смернице</translation>
<translation id="5172758083709347301">Рачунар</translation>
-<translation id="5179510805599951267">Није <ph name="ORIGINAL_LANGUAGE"/>? Пријавите ову грешку</translation>
+<translation id="5179510805599951267">Није <ph name="ORIGINAL_LANGUAGE" />? Пријавите ову грешку</translation>
<translation id="5190835502935405962">Трака са обележивачима</translation>
+<translation id="5199729219167945352">Експерименти</translation>
+<translation id="5251803541071282808">Клауд</translation>
<translation id="5295309862264981122">Потврда навигације</translation>
<translation id="5299298092464848405">Грешка при рашчлањивању смерница</translation>
+<translation id="5316812925700871227">Окрените у смеру супротном од казаљке на сату</translation>
<translation id="5317780077021120954">Сачувај</translation>
<translation id="536296301121032821">Складиштење подешавања смерница није успело</translation>
-<translation id="5439770059721715174">Грешка у валидацији шеме на „<ph name="ERROR_PATH"/>“: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат тренутно није важећи. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
+<translation id="5439770059721715174">Грешка у валидацији шеме на „<ph name="ERROR_PATH" />“: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Неисправна временска ознака смерница</translation>
<translation id="5470861586879999274">&amp;Понови измену</translation>
<translation id="5509780412636533143">Обележивачи којим се управља</translation>
<translation id="5523118979700054094">Назив смерница</translation>
<translation id="552553974213252141">Да ли је текст правилно издвојен?</translation>
<translation id="5540224163453853">Нисмо пронашли захтевани чланак.</translation>
+<translation id="5556459405103347317">Учитај поново</translation>
<translation id="5565735124758917034">Активно</translation>
<translation id="560412284261940334">Управљање није подржано</translation>
<translation id="5629630648637658800">Учитавање подешавања смерница није успело</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Тренутни корисник</translation>
<translation id="5813119285467412249">&amp;Понови додавање</translation>
<translation id="5872918882028971132">Предлози родитеља</translation>
-<translation id="587701087903783706">Затвори приказ прилагођен мобилним уређајима</translation>
<translation id="59107663811261420">Google Payments не подржава овај тип картице за овог продавца. Изаберите неку другу картицу.</translation>
+<translation id="5975083100439434680">Умањивање</translation>
<translation id="5989320800837274978">Нису наведени ни фиксни прокси сервери нити URL адреса .pac скрипте.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Затвори</translation>
+<translation id="6060685159320643512">Пазите, ови експерименти могу бити опасни</translation>
+<translation id="6151417162996330722">Сертификат сервера има предугачак период важења.</translation>
<translation id="6154808779448689242">Враћени токен смерница се не подудара са тренутним токеном</translation>
<translation id="6165508094623778733">Сазнајте више</translation>
<translation id="6259156558325130047">&amp;Понови промену редоследа</translation>
-<translation id="6263376278284652872">Обележивачи домена <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Обележивачи домена <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Поштански број</translation>
<translation id="6337534724793800597">Филтрирај смернице према називу</translation>
+<translation id="6387478394221739770">Интересују вас нове занимљиве Chrome функције? Испробајте бета канал на chrome.com/beta.</translation>
+<translation id="6426993025560594914">Сви експерименти су доступни на платформи!</translation>
<translation id="6445051938772793705">Земља</translation>
<translation id="6458467102616083041">Занемарује се зато што ове смернице онемогућавају подразумевану претрагу.</translation>
<translation id="647261751007945333">Смернице за уређај</translation>
<translation id="6512448926095770873">Затвори ову страницу</translation>
<translation id="6529602333819889595">&amp;Понови брисање</translation>
<translation id="6550675742724504774">Опције</translation>
-<translation id="6597614308054261376">Покушавате да одете на <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Уштеда података тренутно не може да пренесе ту страницу.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> претрага</translation>
+<translation id="6597614308054261376">Покушавате да одете на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Уштеда података тренутно не може да пренесе ту страницу.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> претрага</translation>
<translation id="6644283850729428850">Ове смернице су застареле.</translation>
<translation id="6646897916597483132">Унесите четвороцифрени CVC који се налази на предњој страни картице</translation>
+<translation id="674375294223700098">Непозната грешка сертификата сервера.</translation>
<translation id="6753269504797312559">Вредност смерница</translation>
<translation id="6831043979455480757">Преведи</translation>
<translation id="6839929833149231406">Област</translation>
<translation id="6874604403660855544">&amp;Понови додавање</translation>
<translation id="6891596781022320156">Ниво смерница није подржан.</translation>
<translation id="6915804003454593391">Корисник:</translation>
+<translation id="6957887021205513506">Изгледа да је сертификат сервера фалсификован.</translation>
<translation id="6965382102122355670">Потврди</translation>
<translation id="6965978654500191972">Уређај</translation>
<translation id="6970216967273061347">Дистрикт</translation>
<translation id="6973656660372572881">Наведени су и фиксни прокси сервери и URL адреса .pac скрипте.</translation>
<translation id="6980028882292583085">JavaScript обавештење</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Покушали сте да посетите <ph name="DOMAIN" />, али је сервер представио сертификат са периодом важења који је предугачак да би био поуздан.</translation>
<translation id="7087282848513945231">Округ</translation>
-<translation id="7108649287766967076">Превод на <ph name="TARGET_LANGUAGE"/> није успео.</translation>
+<translation id="7108649287766967076">Превод на <ph name="TARGET_LANGUAGE" /> није успео.</translation>
<translation id="7139724024395191329">Емират</translation>
+<translation id="7179921470347911571">Поново покрени</translation>
<translation id="7180611975245234373">Освежи</translation>
<translation id="7182878459783632708">Нису подешене никакве смернице</translation>
-<translation id="7186367841673660872">Ова страница је преведена са језика:<ph name="ORIGINAL_LANGUAGE"/>на<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="7186367841673660872">Ова страница је преведена са језика:<ph name="ORIGINAL_LANGUAGE" />на<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Претражи <ph name="SEARCH_TERMS"/> на <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">Претражи <ph name="SEARCH_TERMS" /> на <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">Није могуће успоставити приватну везу са доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> јер време и датум на рачунару (<ph name="DATE_AND_TIME" />) нису тачни.</translation>
<translation id="7275334191706090484">Обележивачи којим се управља</translation>
<translation id="7298195798382681320">Препоручено</translation>
<translation id="7334320624316649418">&amp;Понови промену редоследа</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Обавезно</translation>
<translation id="7542995811387359312">Онемогућено је аутоматско попуњавање кредитне картице зато што овај образац не користи безбедну везу.</translation>
-<translation id="7568593326407688803">Ова страница је на језику:<ph name="ORIGINAL_LANGUAGE"/>Желите ли да је преведете?</translation>
+<translation id="7567204685887185387">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат је можда лажно издат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
+<translation id="7568593326407688803">Ова страница је на језику:<ph name="ORIGINAL_LANGUAGE" />Желите ли да је преведете?</translation>
<translation id="7569952961197462199">Желите ли да уклоните кредитну картицу из Chrome-а?</translation>
-<translation id="7600965453749440009">Никад не преводи <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Вредност је изван опсега <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Сертификат сервера крши ограничења за име.</translation>
+<translation id="7600965453749440009">Никад не преводи <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Вредност је изван опсега <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Интересују вас нове занимљиве Chrome функције? Испробајте програмерски канал на chrome.com/dev.</translation>
<translation id="7752995774971033316">Не управља</translation>
+<translation id="7761701407923456692">Сертификат сервера се не подудара са URL адресом.</translation>
<translation id="777702478322588152">Префектура</translation>
<translation id="7791543448312431591">Додај</translation>
<translation id="7805768142964895445">Статус</translation>
<translation id="7813600968533626083">Желите ли да уклоните предлог из Chrome-а?</translation>
<translation id="7887683347370398519">Проверите CVC и покушајте поново</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Сертификат сервера још увек није важећи.</translation>
<translation id="7956713633345437162">Обележивачи на мобилном уређају</translation>
<translation id="7961015016161918242">Никад</translation>
<translation id="7977590112176369853">&lt;унесите упит&gt;</translation>
-<translation id="7983301409776629893">Увек преводи са језика: <ph name="ORIGINAL_LANGUAGE"/> на <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Увек преводи са језика: <ph name="ORIGINAL_LANGUAGE" /> на <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Обележивачи на рачунару</translation>
<translation id="7995512525968007366">Није наведено</translation>
-<translation id="8034522405403831421">Језик ове странице је <ph name="SOURCE_LANGUAGE"/>. Желите ли да је преведете на <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Замена смерница за предузеће</translation>
+<translation id="8034522405403831421">Језик ове странице је <ph name="SOURCE_LANGUAGE" />. Желите ли да је преведете на <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Прегледање чланка није успело.</translation>
<translation id="8091372947890762290">Активација је на чекању на серверу</translation>
<translation id="8194797478851900357">&amp;Опозови премештање</translation>
-<translation id="8201077131113104583">Неважећи URL за ажурирање за додатак са ИД-ом „<ph name="EXTENSION_ID"/>“.</translation>
+<translation id="8201077131113104583">Неважећи URL за ажурирање за додатак са ИД-ом „<ph name="EXTENSION_ID" />“.</translation>
<translation id="8208216423136871611">Не чувај</translation>
<translation id="8218327578424803826">Додељена локација:</translation>
<translation id="8249320324621329438">Последње учитано:</translation>
+<translation id="8294431847097064396">Извор</translation>
<translation id="8308427013383895095">Превођење није успело због проблема са мрежном везом.</translation>
<translation id="8311778656528046050">Да ли стварно желите да поново учитате ову страницу?</translation>
<translation id="8349305172487531364">Трака са обележивачима</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Односе се на</translation>
<translation id="8530504477309582336">Google Payments не подржава овај тип картице. Изаберите неку другу картицу.</translation>
<translation id="8553075262323480129">Превод није успео јер језик странице није могао да буде утврђен.</translation>
-<translation id="8571890674111243710">Превођење странице на <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Није могуће успоставити приватну везу са доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> јер датум и време на уређају (<ph name="DATE_AND_TIME" />) нису тачни.</translation>
+<translation id="8571890674111243710">Превођење странице на <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Врати све на подразумевано</translation>
<translation id="8713130696108419660">Неисправан потпис иницијалима</translation>
<translation id="8725066075913043281">Покушајте поново</translation>
+<translation id="8738058698779197622">Да бисте успоставили безбедну везу, сат на уређају мора да буде тачан. То је зато што сертификати које веб-сајтови користе за идентификацију важе само одређени временски период. Пошто сат на вашем уређају није тачан, Chromium не може да верификује ове сертификате.</translation>
<translation id="8790007591277257123">&amp;Понови брисање</translation>
<translation id="8804164990146287819">Политика приватности</translation>
+<translation id="8820817407110198400">Обележивачи</translation>
<translation id="8824019021993735287">Chrome овог пута није успео да верификује картицу. Покушајте поново касније.</translation>
<translation id="8834246243508017242">Омогућавање аутоматског попуњавања контактима…</translation>
<translation id="883848425547221593">Остали обележивачи</translation>
+<translation id="884923133447025588">Није пронађен ниједан механизам опозива.</translation>
<translation id="8866481888320382733">Грешка при рашчлањивању подешавања смерница</translation>
<translation id="8876793034577346603">Рашчлањивање конфигурације мреже није успело.</translation>
<translation id="8891727572606052622">Неважећи режим проксија.</translation>
-<translation id="8940229512486821554">Покрените <ph name="EXTENSION_NAME"/> команду: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Жао нам је, овај експеримент није доступан на платформи.</translation>
+<translation id="8903921497873541725">Увећавање</translation>
+<translation id="8932102934695377596">Сат вам касни</translation>
+<translation id="8940229512486821554">Покрените <ph name="EXTENSION_NAME" /> команду: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Сертификат сервера је истекао.</translation>
<translation id="8988760548304185580">Унесите датум истека и троцифрени CVC који се налази на полеђини картице</translation>
-<translation id="9020542370529661692">Ова страница је преведена на <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Ознаке које се примењују у целом систему може да подеси само власник: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Ова страница је преведена на <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Покушали сте да дођете до домена <ph name="DOMAIN" />, али сервер је послао неважећи сертификат.</translation>
<translation id="9125941078353557812">Унесите троцифрени CVC који се налази на полеђини картице</translation>
<translation id="9137013805542155359">Прикажи оригинал</translation>
<translation id="9148507642005240123">&amp;Опозови измену</translation>
<translation id="9154176715500758432">Остани на овој страници</translation>
<translation id="9170848237812810038">&amp;Опозови</translation>
+<translation id="917450738466192189">Сертификат сервера је неважећи.</translation>
+<translation id="9187827965378254003">Ах, изгледа да тренутно нема доступних експеримената.</translation>
<translation id="9207861905230894330">Додавање чланка није успело.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ОБРИШИ ОБРАЗАЦ</translation>
+<translation id="988159990683914416">Верзија за програмере</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_sv.xtb b/chromium/components/strings/components_strings_sv.xtb
index ac5c5cdb9e3..f77fd4ea9ed 100644
--- a/chromium/components/strings/components_strings_sv.xtb
+++ b/chromium/components/strings/components_strings_sv.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="sv">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sv">
+<translation id="1032854598605920125">Rotera medurs</translation>
<translation id="1055184225775184556">&amp;Ångra Lägg till</translation>
<translation id="106701514854093668">Bokmärken på skrivbordet</translation>
-<translation id="1103523840287552314">Översätt alltid <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Anpassa till fönstrets bredd</translation>
+<translation id="1103523840287552314">Översätt alltid <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Ångra Ändra ordning</translation>
<translation id="111844081046043029">Vill du lämna den här sidan?</translation>
<translation id="112840717907525620">Cacheminnet för policyn är OK</translation>
<translation id="1132774398110320017">Inställningar för Autofyll i Chrome …</translation>
-<translation id="1152921474424827756">Öppna en <ph name="BEGIN_LINK"/>cachad kopia<ph name="END_LINK"/> av <ph name="URL"/></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="1152921474424827756">Öppna en <ph name="BEGIN_LINK" />cachad kopia<ph name="END_LINK" /> av <ph name="URL" /></translation>
+<translation id="121201262018556460">Du försökte öppna <ph name="DOMAIN" />, men servern visade ett certifikat som signerats med en svag nyckel. Det innebär att den privata nyckeln som servern visar kan vara en förfalskning och att servern kanske inte är den server du tror (du kanske kommunicerar med en skadlig server).</translation>
<translation id="1227224963052638717">Okänd policy.</translation>
<translation id="1227633850867390598">Dölj värde</translation>
<translation id="1228893227497259893">Fel enhetsidentifierare</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Registreringsdomän:</translation>
<translation id="1344588688991793829">Inställningar för Autofyll i Chromium …</translation>
<translation id="1426410128494586442">Ja</translation>
+<translation id="1430915738399379752">Skriv ut</translation>
<translation id="1455235771979731432">Det gick inte att verifiera kortet. Kontrollera internetanslutningen och försök igen.</translation>
<translation id="1491151370853475546">Hämta sidan igen</translation>
<translation id="1549470594296187301">JavaScript måste aktiveras för att du ska kunna använda den här funktionen.</translation>
-<translation id="1639239467298939599">Läser in</translation>
<translation id="1640180200866533862">Användarpolicyer</translation>
<translation id="1644184664548287040">Nätverkskonfigurationen är ogiltig och kan inte importeras.</translation>
-<translation id="1693754753824026215">Sidan på <ph name="SITE"/> säger:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat gick ut i går. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. Dagens datum är <ph name="CURRENT_DATE" /> enligt datorklockan. Går den rätt? I annat fall bör du ställa om datorklockan och sedan uppdatera sidan.}other{Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat gick ut för # dagar sedan. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. Dagens datum är <ph name="CURRENT_DATE" /> enligt datorklockan. Går den rätt? I annat fall bör du ställa om datorklockan och sedan uppdatera sidan.}}</translation>
+<translation id="168841957122794586">Servercertifikatet innehåller en svag kryptografisk nyckel.</translation>
+<translation id="1693754753824026215">Sidan på <ph name="SITE" /> säger:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom enhetens operativsystem inte litar på dess säkerhetscertifikat. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
<translation id="1821930232296380041">Begäran eller parametrar i begäran var ogiltiga</translation>
-<translation id="1853748787962613237">Det gick inte att visa artikeln.</translation>
<translation id="1871208020102129563">Proxyn är inställd på att använda fasta proxyservrar, inte en webbadress med PAC-skript.</translation>
-<translation id="1875753206475436906">heuristisk typ: <ph name="HEURISTIC_TYPE"/>
- servertyp: <ph name="SERVER_TYPE"/>
- fältsignatur: <ph name="FIELD_SIGNATURE"/>
- formulärsignatur: <ph name="FORM_SIGNATURE"/>
- experiment-id: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Öppna <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Bokmärken på <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Öppna <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Bokmärken på <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Serieproduktionsfel</translation>
+<translation id="1974060860693918893">Avancerat</translation>
<translation id="2025186561304664664">Proxyn är inställd på automatisk konfiguration.</translation>
<translation id="2025623846716345241">Bekräfta ny sidhämtning</translation>
-<translation id="2030481566774242610">Menade du <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Menade du <ph name="LINK" />?</translation>
<translation id="2053553514270667976">ZIP</translation>
<translation id="20817612488360358">Datorns proxyinställningar är inställda på att användas, men det finns också en explicit proxykonfiguration.</translation>
<translation id="2094505752054353250">Domänen matchar inte</translation>
<translation id="2096368010154057602">Departement</translation>
<translation id="2113977810652731515">Kort</translation>
-<translation id="2114841414352855701">Ignoreras eftersom den åsidosätts av <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Ignoreras eftersom den åsidosätts av <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Bokmärken i mobilen</translation>
+<translation id="2171101176734966184">Du försökte öppna <ph name="DOMAIN" />, men servern visade ett certifikat som signerats med en svag signaturalgoritm. Det innebär att säkerhetsuppgifterna 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="2181821976797666341">Policyer</translation>
<translation id="2212735316055980242">Policyn hittades inte</translation>
<translation id="2213606439339815911">Hämtar poster …</translation>
<translation id="225207911366869382">Värdet är inte längre giltigt för policyn.</translation>
<translation id="2262243747453050782">HTTP-fel</translation>
-<translation id="2270192940992995399">Det gick inte att hitta artikeln.</translation>
-<translation id="2328300916057834155">Ignorerade ogiltigt bokmärke vid index <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Otillgängliga experiment</translation>
+<translation id="229702904922032456">Ett rotcertifikat eller indirekt certifikat har upphört att gälla.</translation>
+<translation id="2328300916057834155">Ignorerade ogiltigt bokmärke vid index <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Övriga bokmärken</translation>
<translation id="2359808026110333948">Fortsätt</translation>
<translation id="2367567093518048410">Nivå</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="2396249848217231973">&amp;Ångra Ta bort</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="2455981314101692989">Webbsidan har inaktiverat Autofyll för det här formuläret.</translation>
<translation id="2479410451996844060">Ogiltig sökadress.</translation>
+<translation id="2491120439723279231">Servercertifikatet innehåller fel.</translation>
<translation id="2495083838625180221">JSON-analysator</translation>
<translation id="2498091847651709837">Läs in ett nytt kort</translation>
<translation id="2556876185419854533">&amp;Ånga Redigera</translation>
-<translation id="2581221116934462656">Vill du att <ph name="PRODUCT_NAME"/> ska översätta sidor skrivna på <ph name="LANGUAGE_NAME"/> på den här webbplatsen nästa gång?</translation>
+<translation id="2581221116934462656">Vill du att <ph name="PRODUCT_NAME" /> ska översätta sidor skrivna på <ph name="LANGUAGE_NAME" /> på den här webbplatsen nästa gång?</translation>
<translation id="2587841377698384444">Id för katalog-API:</translation>
<translation id="2597378329261239068">Dokumentet är lösenordsskyddat. Ange ett lösenord.</translation>
+<translation id="2625385379895617796">Klockan går före</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2653659639078652383">Skicka</translation>
<translation id="2704283930420550640">Värdet matchar inte formatet.</translation>
<translation id="2721148159707890343">Begäran genomfördes</translation>
+<translation id="2728127805433021124">Serverns certifikat är signerat med en svag signaturalgoritm.</translation>
<translation id="2774256287122201187">Du kan fortsätta. Om du fortsätter till sidan visas inte den här varningen igen på fem minuter.</translation>
<translation id="277499241957683684">Enhetsregister saknas</translation>
<translation id="2835170189407361413">Rensa formuläret</translation>
-<translation id="2855922900409897335">Verifiera ditt <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Verifiera ditt <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat har upphört att gälla. Detta kan bero på en felaktig inställning eller att en angripare har manipulerat anslutningen. Klockan på datorn är för närvarande inställd på <ph name="CURRENT_TIME" />. Stämmer det inte? Korrigera systemets klocka och uppdatera sedan sidan.</translation>
+<translation id="2922350208395188000">Servercertifikatet kan inte kontrolleras.</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="2958431318199492670">Nätverkskonfigurationen uppfyller inte ONC-standarden. Det kan hända att delar av konfigurationen inte kan importeras.</translation>
<translation id="2972581237482394796">&amp;Upprepa</translation>
-<translation id="3010559122411665027">Listposten <ph name="ENTRY_INDEX"/>: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Listposten <ph name="ENTRY_INDEX" />: <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Felaktig policytyp</translation>
<translation id="3105172416063519923">Tillgångs-id:</translation>
<translation id="3145945101586104090">Det gick inte att avkoda svaret</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ö</translation>
<translation id="3219579145727097045">Ange utgångsdatum och den fyrsiffriga CVC-koden på kortets framsida</translation>
-<translation id="3228969707346345236">Det gick inte att översätta eftersom sidan redan är på <ph name="LANGUAGE"/>.</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="3228969707346345236">Det gick inte att översätta eftersom sidan redan är på <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Ångra Ändra ordning</translation>
+<translation id="3286538390144397061">Starta om nu</translation>
<translation id="333371639341676808">Förhindra att den här sidan öppnar ytterligare dialogrutor.</translation>
-<translation id="3369366829301677151">Uppdatera och verifiera ditt <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">inställningar</translation>
+<translation id="3369192424181595722">Fel på klockan</translation>
+<translation id="3369366829301677151">Uppdatera och verifiera ditt <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Tagen ur bruk</translation>
<translation id="3377188786107721145">Fel vid analys av policyn</translation>
<translation id="3380365263193509176">Okänt fel</translation>
<translation id="3380864720620200369">Klient-ID:</translation>
<translation id="3427342743765426898">&amp;Gör om Redigera</translation>
+<translation id="3435896845095436175">Aktivera</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Hämta intervall:</translation>
+<translation id="3462200631372590220">Dölja avancerade uppgifter</translation>
+<translation id="3528171143076753409">Servercertifikatet är inte tillförlitligt.</translation>
<translation id="3542684924769048008">Använd lösenord för:</translation>
<translation id="3583757800736429874">&amp;Gör om Flytta</translation>
<translation id="3623476034248543066">Visa värde</translation>
+<translation id="3648607100222897006">Dessa experimentella funktioner kan ändras, avbrytas eller försvinna när som helst. Vi lämnar inga som helst garantier om vad som kan ske om du aktiverar något av dessa experiment. Webbläsaren kanske t.o.m. går upp i rök. Skämt åsido, alla data i webbläsaren kan raderas och säkerheten och sekretessen kan äventyras på oväntade sätt. Experiment som du aktiverar kommer att aktiveras för alla som använder webbläsaren. Var försiktig.</translation>
<translation id="3650584904733503804">Valideringen har genomförts</translation>
<translation id="370665806235115550">Laddar...</translation>
<translation id="3712624925041724820">Licenserna har tagit slut</translation>
<translation id="3739623965217189342">Länk som du har kopierat</translation>
<translation id="375403751935624634">Det gick inte att översätta på grund av ett serverfel.</translation>
<translation id="385051799172605136">Bakåt</translation>
+<translation id="3858027520442213535">Uppdatera datum och tid</translation>
<translation id="3884278016824448484">Motstridiga enhetsidentifierare</translation>
<translation id="3885155851504623709">Församling</translation>
<translation id="3934680773876859118">Det gick inte att läsa in PDF-dokumentet</translation>
<translation id="3963721102035795474">Läsarläge</translation>
<translation id="4030383055268325496">&amp;Ångra Lägg till</translation>
-<translation id="4058922952496707368">Nyckel <ph name="SUBKEY"/>: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">VARNING</translation>
+<translation id="4058922952496707368">Nyckel <ph name="SUBKEY" />: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Proxykonfigurationen är inställd på att använda en webbadress med PAC-skript, inte fasta proxyservrar.</translation>
<translation id="409504436206021213">Hämta inte sidan igen</translation>
<translation id="4103249731201008433">Enhetens serienummer är ogiltigt</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Felaktig signatur</translation>
<translation id="4269787794583293679">(Inget användarnamn)</translation>
<translation id="4300246636397505754">Föräldratips</translation>
-<translation id="4372948949327679948">Ett <ph name="VALUE_TYPE"/>-värde förväntades.</translation>
+<translation id="4325863107915753736">Det gick inte att hitta artikeln</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="4394049700291259645">Inaktivera</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="443673843213245140">Användning av proxy är inaktiverad men en explicit proxykonfiguration har angetts.</translation>
-<translation id="4506176782989081258">Valideringsfel: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Valideringsfel: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Vill du ta bort adressen från Chrome?</translation>
<translation id="4594403342090139922">&amp;Ångra Ta bort</translation>
<translation id="4607653538520819196">Sidan kan inte skickas som proxy av Databesparing.</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="4726672564094551039">Läs in policyer på nytt</translation>
+<translation id="4728558894243024398">Plattform</translation>
+<translation id="4771973620359291008">Ett okänt fel uppstod.</translation>
<translation id="4800132727771399293">Kontrollera utgångsdatum och CVC-kod och försök igen</translation>
<translation id="4813512666221746211">Nätverksfel</translation>
+<translation id="4816492930507672669">Anpassa till sida</translation>
<translation id="4850886885716139402">Visa</translation>
-<translation id="4923417429809017348">Sidan har översatts från ett okänt språk till <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Sidan har översatts från ett okänt språk till <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Värdet måste anges.</translation>
<translation id="4968547170521245791">Kan inte skicka som proxy</translation>
-<translation id="498957508165411911">Vill du översätta från <ph name="ORIGINAL_LANGUAGE"/> till <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Vill du översätta från <ph name="ORIGINAL_LANGUAGE" /> till <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Säkerhetskopian har dålig status</translation>
<translation id="5031870354684148875">Om Google Översätt</translation>
+<translation id="5045550434625856497">Felaktigt lösenord</translation>
+<translation id="5087286274860437796">Servercertifikatet är inte giltigt för närvarande.</translation>
<translation id="5089810972385038852">Delstat</translation>
+<translation id="5094747076828555589">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom Chromium inte litar på dess säkerhetscertifikat. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
<translation id="5095208057601539847">Provins</translation>
<translation id="5145883236150621069">Felkoden ingår i policysvaret</translation>
<translation id="5172758083709347301">Dator</translation>
-<translation id="5179510805599951267">Inte på <ph name="ORIGINAL_LANGUAGE"/>? Rapportera felet</translation>
+<translation id="5179510805599951267">Inte på <ph name="ORIGINAL_LANGUAGE" />? Rapportera felet</translation>
<translation id="5190835502935405962">Bokmärkesfältet</translation>
+<translation id="5199729219167945352">Experiment</translation>
+<translation id="5251803541071282808">Moln</translation>
<translation id="5295309862264981122">Bekräfta navigering</translation>
<translation id="5299298092464848405">Det uppstod ett fel när policyn analyserades</translation>
+<translation id="5316812925700871227">Rotera moturs</translation>
<translation id="5317780077021120954">Spara</translation>
<translation id="536296301121032821">Det gick inte att spara policyinställningarna</translation>
-<translation id="5439770059721715174">Schemavalideringsfel i <ph name="ERROR_PATH"/>: <ph name="ERROR"/></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="5439770059721715174">Schemavalideringsfel i <ph name="ERROR_PATH" />: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Felaktig tidsstämpel för policy</translation>
<translation id="5470861586879999274">&amp;Gör om Redigera</translation>
<translation id="5509780412636533143">Hanterade bokmärken</translation>
<translation id="5523118979700054094">Policynamn</translation>
<translation id="552553974213252141">Extraherades texten korrekt?</translation>
<translation id="5540224163453853">Det gick inte att hitta den önskade artikeln.</translation>
+<translation id="5556459405103347317">Hämta igen</translation>
<translation id="5565735124758917034">Aktiv</translation>
<translation id="560412284261940334">Hantering stöds inte</translation>
<translation id="5629630648637658800">Det gick inte att läsa in policyinställningarna</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Aktuell användare</translation>
<translation id="5813119285467412249">&amp;Gör om Lägg till</translation>
<translation id="5872918882028971132">Föräldratips</translation>
-<translation id="587701087903783706">Stäng den mobilanpassade vyn</translation>
<translation id="59107663811261420">Den här korttypen stöds inte i Google Payments för den här säljaren. Välj ett annat kort.</translation>
+<translation id="5975083100439434680">Zooma ut</translation>
<translation id="5989320800837274978">Varken fasta proxyservrar eller en webbadress med PAC-skript har angetts.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Stäng</translation>
+<translation id="6060685159320643512">Försiktigt, experimenten kan vara skadliga</translation>
+<translation id="6151417162996330722">Servercertifikatet har för lång giltighetstid.</translation>
<translation id="6154808779448689242">Returnerad policytoken matchade inte den aktuella token</translation>
<translation id="6165508094623778733">Läs mer</translation>
<translation id="6259156558325130047">&amp;Gör om Ändra ordning</translation>
-<translation id="6263376278284652872">Bokmärken för <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Bokmärken för <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Postnummer</translation>
<translation id="6337534724793800597">Filtrera policy efter namn</translation>
+<translation id="6387478394221739770">Är du intresserad av häftiga nya funktioner i Chrome? Pröva vår betakanal på chrome.com/beta.</translation>
+<translation id="6426993025560594914">Alla experiment finns på din plattform!</translation>
<translation id="6445051938772793705">Land</translation>
<translation id="6458467102616083041">Ignoreras eftersom standardsökmotorn är inaktiverad av en policy.</translation>
<translation id="647261751007945333">Enhetspolicyer</translation>
<translation id="6512448926095770873">Lämna denna sida</translation>
<translation id="6529602333819889595">&amp;Gör om Ta bort</translation>
<translation id="6550675742724504774">Alternativ</translation>
-<translation id="6597614308054261376">Du försöker nå <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Sidan kan inte skickas som proxy av Databesparing för tillfället.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Sök</translation>
+<translation id="6597614308054261376">Du försöker nå <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Sidan kan inte skickas som proxy av Databesparing för tillfället.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Sök</translation>
<translation id="6644283850729428850">Policyn är föråldrad.</translation>
<translation id="6646897916597483132">Ange den fyrsiffriga CVC-koden från kortets framsida</translation>
+<translation id="674375294223700098">Fel - okänt servercertifikat.</translation>
<translation id="6753269504797312559">Policyvärde</translation>
<translation id="6831043979455480757">Översätt</translation>
<translation id="6839929833149231406">Huvudområde</translation>
<translation id="6874604403660855544">&amp;Gör om Lägg till</translation>
<translation id="6891596781022320156">Policynivån stöds inte.</translation>
<translation id="6915804003454593391">Användare:</translation>
+<translation id="6957887021205513506">Serverns certifikat verkar vara falskt.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">JavaScript-varning</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Du försökte nå <ph name="DOMAIN" />, men servern svarade med ett certifikat vars giltighetstid är för lång för att det ska vara trovärdigt.</translation>
<translation id="7087282848513945231">Grevskap</translation>
-<translation id="7108649287766967076">Översättningen till <ph name="TARGET_LANGUAGE"/> misslyckades.</translation>
+<translation id="7108649287766967076">Översättningen till <ph name="TARGET_LANGUAGE" /> misslyckades.</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7179921470347911571">Starta om nu</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="7186367841673660872">Sidan har översatts från<ph name="ORIGINAL_LANGUAGE" />till<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Sök i <ph name="SITE_NAME"/> efter <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Sök i <ph name="SITE_NAME" /> efter <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Det gick inte att upprätta en privat anslutning till <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> eftersom datorns datum och tid (<ph name="DATE_AND_TIME" />) inte stämmer.</translation>
<translation id="7275334191706090484">Hanterade bokmärken</translation>
<translation id="7298195798382681320">Rekommenderas</translation>
<translation id="7334320624316649418">&amp;Gör om Ändra ordning</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Obligatorisk</translation>
<translation id="7542995811387359312">Automatisk ifyllning av kreditkort har inaktiverats eftersom formulärets anslutning inte är säker.</translation>
-<translation id="7568593326407688803">Den här sidan är på<ph name="ORIGINAL_LANGUAGE"/>Vill du översätta den?</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="7568593326407688803">Den här sidan är på<ph name="ORIGINAL_LANGUAGE" />Vill du översätta den?</translation>
<translation id="7569952961197462199">Vill du ta bort kreditkortet från Chrome?</translation>
-<translation id="7600965453749440009">Översätt aldrig från <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Värdet är utanför intervallet <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Serverns certifikat strider mot namnrestriktionerna.</translation>
+<translation id="7600965453749440009">Översätt aldrig från <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Värdet är utanför intervallet <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Är du intresserad av häftiga nya funktioner i Chrome? Pröva vår utvecklarkanal på chrome.com/dev.</translation>
<translation id="7752995774971033316">Hanteras inte</translation>
+<translation id="7761701407923456692">Servercertifikatet överensstämmer inte med webbadressen.</translation>
<translation id="777702478322588152">Prefektur</translation>
<translation id="7791543448312431591">Lägg till</translation>
<translation id="7805768142964895445">Status</translation>
<translation id="7813600968533626083">Vill du ta bort formulärförslaget från Chrome?</translation>
<translation id="7887683347370398519">Kontrollera CVC-koden och försök igen</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Servercertifikatet är inte giltigt ännu.</translation>
<translation id="7956713633345437162">Bokmärken i mobilen</translation>
<translation id="7961015016161918242">Aldrig</translation>
<translation id="7977590112176369853">&lt;skriv fråga&gt;</translation>
-<translation id="7983301409776629893">Översätt alltid <ph name="ORIGINAL_LANGUAGE"/> till <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Översätt alltid <ph name="ORIGINAL_LANGUAGE" /> till <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Bokmärken på skrivbordet</translation>
<translation id="7995512525968007366">Inte specificerad</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="8003882219468422867">Åsidosättning gäller i företaget</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="8088680233425245692">Det gick inte att visa artikeln.</translation>
<translation id="8091372947890762290">Aktiveringen väntar på servern</translation>
<translation id="8194797478851900357">&amp;Ångra Flytta</translation>
-<translation id="8201077131113104583">Ogiltig webbadress för uppdatering för tillägg med id <ph name="EXTENSION_ID"/>.</translation>
+<translation id="8201077131113104583">Ogiltig webbadress för uppdatering för tillägg med id <ph name="EXTENSION_ID" />.</translation>
<translation id="8208216423136871611">Spara inte</translation>
<translation id="8218327578424803826">Tilldelad plats:</translation>
<translation id="8249320324621329438">Senast hämtad:</translation>
+<translation id="8294431847097064396">Källa</translation>
<translation id="8308427013383895095">Det gick inte att översätta på grund av ett nätverksfel.</translation>
<translation id="8311778656528046050">Vill du hämta sidan igen?</translation>
<translation id="8349305172487531364">Bokmärkesfältet</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Gäller för</translation>
<translation id="8530504477309582336">Den här korttypen stöds inte i Google Payments. Välj ett annat kort.</translation>
<translation id="8553075262323480129">Det gick inte att översätta eftersom det inte gick att avgöra vilket språk som användes på sidan.</translation>
-<translation id="8571890674111243710">Översätter sidan till <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Det gick inte att upprätta en privat anslutning till <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> eftersom enhetens datum och tid (<ph name="DATE_AND_TIME" />) inte stämmer.</translation>
+<translation id="8571890674111243710">Översätter sidan till <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Återställ alla till standardvärden</translation>
<translation id="8713130696108419660">Dålig initial signatur</translation>
<translation id="8725066075913043281">Försök igen</translation>
+<translation id="8738058698779197622">Om du vill upprätta en säker anslutning måste klockan vara rätt inställd. Det beror på att certifikaten som webbplatserna använder för att identifiera sig endast är giltiga under vissa tidsperioder. Chromium kan inte verifiera certifikaten eftersom klockan på enheten inte stämmer.</translation>
<translation id="8790007591277257123">&amp;Gör om Ta bort</translation>
<translation id="8804164990146287819">Sekretesspolicy</translation>
+<translation id="8820817407110198400">Bokmärken</translation>
<translation id="8824019021993735287">Det gick inte att verifiera kortet. Försök igen senare.</translation>
<translation id="8834246243508017242">Aktivera Autofyll från Kontakter …</translation>
<translation id="883848425547221593">Övriga bokmärken</translation>
+<translation id="884923133447025588">Ingen återkallningsmekanism har hittats.</translation>
<translation id="8866481888320382733">Det uppstod ett fel när policyinställningarna analyserades</translation>
<translation id="8876793034577346603">Det gick inte att tolka nätverkskonfigurationen.</translation>
<translation id="8891727572606052622">Ogiltigt proxyläge.</translation>
-<translation id="8940229512486821554">Kör kommandot <ph name="EXTENSION_NAME"/> för: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Experimentet finns tyvärr inte på din plattform.</translation>
+<translation id="8903921497873541725">Zooma in</translation>
+<translation id="8932102934695377596">Klockan går efter</translation>
+<translation id="8940229512486821554">Kör kommandot <ph name="EXTENSION_NAME" /> för: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Servercertifikatet har gått ut.</translation>
<translation id="8988760548304185580">Ange utgångsdatum och den tresiffriga CVC-koden på kreditkortets baksida</translation>
-<translation id="9020542370529661692">Den här sidan har översatts till <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Flaggor som gäller hela systemet kan endast ställas in av ägaren: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Den här sidan har översatts till <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Du försökte nå <ph name="DOMAIN" /> men servern angav ett ogiltigt certifikat.</translation>
<translation id="9125941078353557812">Ange den tresiffriga CVC-koden från kortets baksida</translation>
<translation id="9137013805542155359">Visa original</translation>
<translation id="9148507642005240123">&amp;Ångra Redigera</translation>
<translation id="9154176715500758432">Stanna på den här sidan</translation>
<translation id="9170848237812810038">&amp;Ångra</translation>
+<translation id="917450738466192189">Servercertifikatet är ogiltigt.</translation>
+<translation id="9187827965378254003">Det verkar inte finnas några experimentfunktioner tillgängliga just nu.</translation>
<translation id="9207861905230894330">Det gick inte att lägga till artikeln.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">RENSA FORMULÄRET</translation>
+<translation id="988159990683914416">Utvecklarversion</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_sw.xtb b/chromium/components/strings/components_strings_sw.xtb
index df50ca8cf70..1b1b489f48e 100644
--- a/chromium/components/strings/components_strings_sw.xtb
+++ b/chromium/components/strings/components_strings_sw.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="sw">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sw">
+<translation id="1032854598605920125">Zungusha kwenye mwendo wa saa</translation>
<translation id="1055184225775184556">Tendua Kuongeza</translation>
<translation id="106701514854093668">Alamisho za Eneokazi</translation>
-<translation id="1103523840287552314">Tafsiri <ph name="LANGUAGE"/> kila wakati</translation>
+<translation id="1080116354587839789">Fanya itoshe kwenye upana</translation>
+<translation id="1103523840287552314">Tafsiri <ph name="LANGUAGE" /> kila wakati</translation>
<translation id="1113869188872983271">Tendua kupanga upya</translation>
<translation id="111844081046043029">Je, una hakika kuwa ungependa kuondoka kwenye ukurasa huu?</translation>
<translation id="112840717907525620">Akiba ya sera ni SAWA</translation>
<translation id="1132774398110320017">Mipangilio ya Kujaza otomatiki ya Chrome...</translation>
-<translation id="1152921474424827756">Fikia <ph name="BEGIN_LINK"/>nakala iliyowekwa kwenye akiba<ph name="END_LINK"/> ya <ph name="URL"/></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="1152921474424827756">Fikia <ph name="BEGIN_LINK" />nakala iliyowekwa kwenye akiba<ph name="END_LINK" /> ya <ph name="URL" /></translation>
+<translation id="121201262018556460">Umejaribu kufikia <ph name="DOMAIN" />, lakini seva iliwasilisha cheti kikiwa na ufunguo duni. Huenda mshambulizi alivunja ufunguo wa siri, na huenda seva isiwe seva ulioitarajia (unaweza kuwa unawasiliana na mshambulizi).</translation>
<translation id="1227224963052638717">Sera isiyojulikana.</translation>
<translation id="1227633850867390598">Ficha thamani</translation>
<translation id="1228893227497259893">Kitambulisho cha huluki kisicho halali</translation>
@@ -14,61 +20,77 @@
<translation id="1339601241726513588">Kikoa cha kujiandikisha:</translation>
<translation id="1344588688991793829">Mipangilio ya Kujaza otomatiki ya Chromium...</translation>
<translation id="1426410128494586442">Ndio</translation>
+<translation id="1430915738399379752">Chapisha</translation>
<translation id="1455235771979731432">Kulikuwa na tatizo wakati wa kuthibitisha kadi yako. Angalia muunganisho wako wa intaneti na ujaribu tena.</translation>
<translation id="1491151370853475546">Pakia Ukurasa huu Upya</translation>
<translation id="1549470594296187301">Lazima JavaScript iwashwe ili utumie kipengele hiki.</translation>
-<translation id="1639239467298939599">Inapakia</translation>
<translation id="1640180200866533862">Sera za mtumiaji</translation>
<translation id="1644184664548287040">Usanidi wa mtandao ni batili na usingeweza kuingizwa.</translation>
-<translation id="1693754753824026215">Ukurasa wa <ph name="SITE"/> unasema:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kilikwisha muda jana. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako. Saa ya kompyuta kwa sasa imewekwa kuwa <ph name="CURRENT_DATE" />. Je, hiyo ni sahihi? Ikiwa si sahihi, rekebisha saa ya mfumo wako kisha uonyeshe upya ukurasa huu.}other{Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kilikwisha muda siku # zilizopita. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako. Saa ya kompyuta kwa sasa imewekwa kuwa <ph name="CURRENT_DATE" />. Je, hiyo ni sahihi? Ikiwa si sahihi, rekebisha saa ya mfumo wako kisha uonyeshe upya ukurasa huu.}}</translation>
+<translation id="168841957122794586">Cheti cha seva kina kitufe dhaifu cha kifichua msimbo.</translation>
+<translation id="1693754753824026215">Ukurasa wa <ph name="SITE" /> unasema:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama hakiaminiwi na mfumo wa uendeshaji wa kifaa chako. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.</translation>
<translation id="1821930232296380041">Ombi au vigezo vya ombi batili</translation>
-<translation id="1853748787962613237">Haikufaulu kuonyesha makala.</translation>
<translation id="1871208020102129563">Proksi imewekwa ili kutumia seva za proksi thabiti, siyo URL ya hati .pac.</translation>
-<translation id="1875753206475436906">aina ya utatuaji wa haraka: <ph name="HEURISTIC_TYPE"/> aina ya seva: <ph name="SERVER_TYPE"/> sehemu ya sahihi: <ph name="FIELD_SIGNATURE"/> fomu ya sahihi: <ph name="FORM_SIGNATURE"/> utambulisho wa majaribio: &quot; <ph name="EXPERIMENT_ID"/> &quot;</translation>
-<translation id="194030505837763158">Nenda kwenye <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Alamisho za <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Nenda kwenye <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Alamisho za <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Hitilafu ya namba tambulishi</translation>
+<translation id="1974060860693918893">Mipangilio ya kina</translation>
<translation id="2025186561304664664">Proksi imewekwa katika usanidi otomatiki.</translation>
<translation id="2025623846716345241">Thibitisha Upakiaji Upya</translation>
-<translation id="2030481566774242610">Je, ulimaanisha <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Je, ulimaanisha <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Msimbo wa eneo</translation>
<translation id="20817612488360358">Mipangilio ya mfumo ya proksi imewekwa ili kutumiwa lakini usanidi dhahiri wa proksi pia umebainishwa.</translation>
<translation id="2094505752054353250">Kitolingana kwa kikoa</translation>
<translation id="2096368010154057602">Idara</translation>
<translation id="2113977810652731515">Kadi</translation>
-<translation id="2114841414352855701">Imepuuzwa kwa sababu ilifutwa na <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Imepuuzwa kwa sababu ilifutwa na <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Mteja Halisi</translation>
<translation id="213826338245044447">Alamisho kwenye Simu</translation>
+<translation id="2171101176734966184">Umejaribu kufikia <ph name="DOMAIN" />, lakini seva iliwasilisha cheti kilichotiwa sahihi na kanuni duni. Hii inamaanisha kuwa stakabadhi za usalama zilizowasilishwa na seva hiyo zinaweza kuwa bandia, na seva hiyo huenda ikawa sio ile uliyotarajia (unaweza kuwa unawasiliana na mshambulizi).</translation>
<translation id="2181821976797666341">Sera</translation>
<translation id="2212735316055980242">Sera haikupatikana</translation>
<translation id="2213606439339815911">Inachukua viingizo...</translation>
<translation id="225207911366869382">Thamani hii inapingwa kwa sera hii.</translation>
<translation id="2262243747453050782">Hitilfau ya HTTP</translation>
-<translation id="2270192940992995399">Haikufaulu kupata makala.</translation>
-<translation id="2328300916057834155">Imepuuzia alamisho batili katika farahasa <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Majaribio Yasiyopatikana</translation>
+<translation id="229702904922032456">Kitambulisho cha mzizi au kati kimekwisha muda.</translation>
+<translation id="2328300916057834155">Imepuuzia alamisho batili katika farahasa <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Alamisho zingine</translation>
<translation id="2359808026110333948">Endelea</translation>
<translation id="2367567093518048410">Kiwango</translation>
+<translation id="2384307209577226199">Biashara chaguo-msingi</translation>
+<translation id="2386255080630008482">Cheti cha seva kimebatilishwa.</translation>
<translation id="2392959068659972793">Onyesha sera zisizowekwa thamani</translation>
<translation id="2396249848217231973">Tendua kufuta</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="2455981314101692989">Ukurasa wavuti huu umelemaza mjazo otomatiki kwa fomu hii.</translation>
<translation id="2479410451996844060">URL batili ya utafutaji.</translation>
+<translation id="2491120439723279231">Cheti cha seva kina hitilafu.</translation>
<translation id="2495083838625180221">Kichanganuzi cha JSON</translation>
<translation id="2498091847651709837">Changanua kadi mpya</translation>
<translation id="2556876185419854533">Tendua Kuhariri</translation>
-<translation id="2581221116934462656">Ungependa <ph name="PRODUCT_NAME"/> itafsiri kurasa za <ph name="LANGUAGE_NAME"/> kutoka tovuti hii wakati ujao?</translation>
+<translation id="2581221116934462656">Ungependa <ph name="PRODUCT_NAME" /> itafsiri kurasa za <ph name="LANGUAGE_NAME" /> kutoka tovuti hii wakati ujao?</translation>
<translation id="2587841377698384444">Kitambulisho cha API ya Saraka:</translation>
<translation id="2597378329261239068">Hati hii imelindwa kwa nenosiri. Tafadhali weka nenosiri linalotumika.</translation>
+<translation id="2625385379895617796">Saa yako iko mbele</translation>
<translation id="2639739919103226564">Hali:</translation>
+<translation id="2653659639078652383">Wasilisha</translation>
<translation id="2704283930420550640">Thamani haioani na umbizo.</translation>
<translation id="2721148159707890343">Ombi limefanikiwa</translation>
+<translation id="2728127805433021124">Cheti cha seva kimetiwa sahihi kwa kutumia algoriti dhaifu ya sahihi.</translation>
<translation id="2774256287122201187">Unaweza kuendelea. Ukienda kwenye ukurasa, onyo hili halitaonekana tena kwa dakika tano.</translation>
<translation id="277499241957683684">Rekodi ya kifaa inayokosekana</translation>
<translation id="2835170189407361413">Futa fomu</translation>
-<translation id="2855922900409897335">Thibitisha kadi yako ya <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Thibitisha kadi yako ya <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kilikwisha muda. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako. Saa ya kompyuta yako imewekwa kwenye saa <ph name="CURRENT_TIME" /> kwa sasa. Hiyo ni sawa? Ikiwa si sawa, unapaswa kurekebisha mfumo wako wa saa kisha uonyeshe upya ukurasa huu.</translation>
+<translation id="2922350208395188000">Cheti cha seva hakiwezi kukaguliwa.</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="2958431318199492670">Usanidi wa mtandao hautii kiwango cha ONC. Sehemu za usanidi haziwezi kuingizwa.</translation>
<translation id="2972581237482394796">&amp;Rudia</translation>
-<translation id="3010559122411665027">Ingizo orodha &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Ingizo orodha "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Aina mbaya ya sera</translation>
<translation id="3105172416063519923">Kitambulisho cha Kipengee:</translation>
<translation id="3145945101586104090">Imeshindwa kusimbua jibu</translation>
@@ -76,32 +98,42 @@
<translation id="3169472444629675720">Gundua</translation>
<translation id="3174168572213147020">Kisiwa</translation>
<translation id="3219579145727097045">Weka tarehe ya kuisha muda na CVC yenye tarakimu 4 kutoka mbele ya kadi yako</translation>
-<translation id="3228969707346345236">Tafsiri ilishindikana kwa sababu ukurasa tayari upo katika <ph name="LANGUAGE"/>.</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="3228969707346345236">Tafsiri ilishindikana kwa sababu ukurasa tayari upo katika <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">Tendua Kupanga upya</translation>
+<translation id="3286538390144397061">Zima na uwashe sasa</translation>
<translation id="333371639341676808">Zuia ukurasa huu usiunde majadiliano zaidi.</translation>
-<translation id="3369366829301677151">Sasisha na uthibitishe kadi yako ya <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">mipangilio</translation>
+<translation id="3369192424181595722">Hitilafu ya saa</translation>
+<translation id="3369366829301677151">Sasisha na uthibitishe kadi yako ya <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Imewekwa katika hali ya kutotumika</translation>
<translation id="3377188786107721145">Hitilafu ya kuchanganua sera</translation>
<translation id="3380365263193509176">Hitilafu isiyojulikana</translation>
<translation id="3380864720620200369">Kitambulisho cha Mteja:</translation>
<translation id="3427342743765426898">Rudia Kuhariri</translation>
+<translation id="3435896845095436175">Washa</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Muda unaotumika kuleta:</translation>
+<translation id="3462200631372590220">Ficha mahiri</translation>
+<translation id="3528171143076753409">Cheti cha seva hakiaminiki.</translation>
<translation id="3542684924769048008">Tumia nenosiri kwa:</translation>
<translation id="3583757800736429874">Rudia Hatua</translation>
<translation id="3623476034248543066">Onyesha thamani</translation>
+<translation id="3648607100222897006">Hivi vipengele vya jaribio vinaweza kubadilika, kuvunjika, au kutoweka wakati wowote. Hatuhakikishi kabisa kuhusu kile kinachoweza kutokea ikiwa utawasha mojawapo ya majaribio haya, na hata kivinjari chako kinaweza kuchoma kighafla. Bila utani, kivinjari kinaweza kufuta data yako yote, au usalama na faragha yako inaweza kuathirika katika njia isiyotarajiwa. Majaribio yote unayoyawezesha yatawezeshwa kwa watumiaji wote wa kivinjari hiki. Tafadhali endelea kwa tahadhari.</translation>
<translation id="3650584904733503804">Uhalalishaji umefanikiwa</translation>
<translation id="370665806235115550">Inapakia...</translation>
<translation id="3712624925041724820">Leseni zimekwisha</translation>
<translation id="3739623965217189342">Kiungo ulichonakili</translation>
<translation id="375403751935624634">Utafsiri haukufanikiwa kwa sababu ya hitilafu ya seva.</translation>
<translation id="385051799172605136">Nyuma</translation>
+<translation id="3858027520442213535">Sasisha tarehe na saa</translation>
<translation id="3884278016824448484">Kitambulisho cha kifaa kinachokinzana</translation>
<translation id="3885155851504623709">Parish</translation>
<translation id="3934680773876859118">Imeshindwa kupakia hati ya PDF</translation>
<translation id="3963721102035795474">Hali ya Usomaji</translation>
<translation id="4030383055268325496">Tendua kuongeza</translation>
-<translation id="4058922952496707368">Kitufe &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ONYO</translation>
+<translation id="4058922952496707368">Kitufe "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Usanidi wa proksi umewekwa kutumia URL hati ya .pac, siyo seva proksi za kudumu.</translation>
<translation id="409504436206021213">Usipakie Upya</translation>
<translation id="4103249731201008433">Namabari tambulishi ya kifaa ni batili</translation>
@@ -114,40 +146,56 @@
<translation id="4258748452823770588">Sahihi mbaya</translation>
<translation id="4269787794583293679">(Hakuna jina la mtumiaji)</translation>
<translation id="4300246636397505754">Mapendekezo ya wazazi</translation>
-<translation id="4372948949327679948">Thamani <ph name="VALUE_TYPE"/> inayotarajiwa.</translation>
+<translation id="4325863107915753736">Haikupata makala</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="4394049700291259645">Zima</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="443673843213245140">Matumizi ya proksi yamelemazwa lakini usanidi wa proksi wazi umebainishwa.</translation>
-<translation id="4506176782989081258">Hitilafu ya uthibitishaji: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Hitilafu ya uthibitishaji: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Ungependa kuondoa anwani kutoka kwenye Chrome?</translation>
<translation id="4594403342090139922">Tendua Kufuta</translation>
<translation id="4607653538520819196">Ukurasa huu hauwezi kuwakilishwa na Kiokoa Data.</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="4726672564094551039">Pakia sera upya</translation>
+<translation id="4728558894243024398">Mfumo wa uendeshaji</translation>
+<translation id="4771973620359291008">Hitilafu isiyojulikana imetokea.</translation>
<translation id="4800132727771399293">Angalia tarehe yako ya kuisha muda na CVC na ujaribu tena</translation>
<translation id="4813512666221746211">Hitilafu ya mtandao</translation>
+<translation id="4816492930507672669">Sawazisha kwenye ukurasa</translation>
<translation id="4850886885716139402">Mwonekano</translation>
-<translation id="4923417429809017348">Ukurasa huu umetafsiriwa kutoka katika lugha ambayo haijulikani hadi <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Ukurasa huu umetafsiriwa kutoka katika lugha ambayo haijulikani hadi <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Sharti ibainishwe.</translation>
<translation id="4968547170521245791">Haiwezi Kuwakilisha</translation>
-<translation id="498957508165411911">Je, ungependa kutafsiri kutoka <ph name="ORIGINAL_LANGUAGE"/> kwenda <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Je, ungependa kutafsiri kutoka <ph name="ORIGINAL_LANGUAGE" /> kwenda <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Hifadhi la kucheleza liko katika hali mbaya</translation>
<translation id="5031870354684148875">Kuhusu Google Tafsiri</translation>
+<translation id="5045550434625856497">Nenosiri lisilo sahihi</translation>
+<translation id="5087286274860437796">Cheti cha seva si sahihi kwa sasa.</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="5145883236150621069">Msimbo wa hitilafu uko katika jibu la sera</translation>
<translation id="5172758083709347301">Mashine</translation>
-<translation id="5179510805599951267">Haiko katika <ph name="ORIGINAL_LANGUAGE"/>? Ripoti hitilafu hii</translation>
+<translation id="5179510805599951267">Haiko katika <ph name="ORIGINAL_LANGUAGE" />? Ripoti hitilafu hii</translation>
<translation id="5190835502935405962">Sehemu ya Alamisho</translation>
+<translation id="5199729219167945352">Majaribio</translation>
+<translation id="5251803541071282808">Wingu</translation>
<translation id="5295309862264981122">Thibitisha unataka kuondoka</translation>
<translation id="5299298092464848405">Hitilafu wakati wa kuchanganua sera</translation>
+<translation id="5316812925700871227">Zungusha kinyume cha mwendo wa saa</translation>
<translation id="5317780077021120954">Hifadhi</translation>
<translation id="536296301121032821">Imeshindwa kuhifadhi mipangilio ya sera</translation>
-<translation id="5439770059721715174">Hitilafu katika uhalalishaji wa Skima &quot; <ph name="ERROR_PATH"/> &quot;: <ph name="ERROR"/></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="5439770059721715174">Hitilafu katika uhalalishaji wa Skima " <ph name="ERROR_PATH" /> ": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Muhuri wa muda wa sera mbaya</translation>
<translation id="5470861586879999274">Rudia kuhariri</translation>
<translation id="5509780412636533143">Alamisho zinazosimamiwa</translation>
<translation id="5523118979700054094">Jina la sera</translation>
<translation id="552553974213252141">Je, maandishi yalitolewa kwa njia sahihi?</translation>
<translation id="5540224163453853">Haikuweza kupata makala yaliyoitishwa.</translation>
+<translation id="5556459405103347317">Pakia upya</translation>
<translation id="5565735124758917034">Inatumika</translation>
<translation id="560412284261940334">Usimamizi hautumiki</translation>
<translation id="5629630648637658800">Imeshindwa kupakia mipangilio ya sera</translation>
@@ -155,46 +203,56 @@
<translation id="5720705177508910913">Mtumiaji wa sasa</translation>
<translation id="5813119285467412249">Rudia Kuongeza</translation>
<translation id="5872918882028971132">Mapendekezo ya Wazazi</translation>
-<translation id="587701087903783706">Funga mwonekano unaosomeka vizuri kwenye kifaa cha mkononi</translation>
<translation id="59107663811261420">Aina hii ya kadi haiwezi kutumiwa na Google Payments kwa muuzaji huyu. Tafadhali teua kadi tofauti.</translation>
+<translation id="5975083100439434680">Fifiza</translation>
<translation id="5989320800837274978">Siyo seva proksi za kudumu wala URL ya hati ya .pac zimebainishwa.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Funga</translation>
+<translation id="6060685159320643512">Tahadhari, majaribio haya yanaweza kusumbua</translation>
+<translation id="6151417162996330722">Cheti cha seva kina muda sahihi ambao ni mrefu sana.</translation>
<translation id="6154808779448689242">Ishara ya sera iliyorejeshwa hailingani na ishara ya sasa</translation>
<translation id="6165508094623778733">Pata maelezo zaidi</translation>
<translation id="6259156558325130047">Rudia Kupanga Upya</translation>
-<translation id="6263376278284652872">Alamisho za <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Alamisho za <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Msimbo wa posta</translation>
<translation id="6337534724793800597">Chuja sera kwa jina</translation>
+<translation id="6387478394221739770">Unavutiwa na vipengee vipya vizuri vya Chrome? Jaribu kituo chetu cha beta katika chrome.com/beta.</translation>
+<translation id="6426993025560594914">Majaribio yote yanapatikana kwenye mfumo wako wa uendeshaji!</translation>
<translation id="6445051938772793705">Nchi</translation>
<translation id="6458467102616083041">Imepuuzwa kwa sababu utafutaji chaguo-msingi unalemazwa kwa sera.</translation>
<translation id="647261751007945333">Sera za kifaa</translation>
<translation id="6512448926095770873">Ondoka kwenye ukurasa huu</translation>
<translation id="6529602333819889595">Rudia Kufuta</translation>
<translation id="6550675742724504774">Chaguo</translation>
-<translation id="6597614308054261376">Unajaribu kufikia <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Ukurasa huu hauwezi kuwakilishwa na Kiokoa Data kwa wakati huu.</translation>
-<translation id="6628463337424475685">Utafutaji wa <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Unajaribu kufikia <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Ukurasa huu hauwezi kuwakilishwa na Kiokoa Data kwa wakati huu.</translation>
+<translation id="6628463337424475685">Utafutaji wa <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Sera hii imepingwa.</translation>
<translation id="6646897916597483132">Weka CVC yenye tarakimu 4 kutoka mbele ya kadi yako</translation>
+<translation id="674375294223700098">Hitilafu isiyojulikana ya cheti cha seva.</translation>
<translation id="6753269504797312559">Thamani ya sera</translation>
<translation id="6831043979455480757">Tafsiri</translation>
<translation id="6839929833149231406">Eneo</translation>
<translation id="6874604403660855544">Rudia kuongeza</translation>
<translation id="6891596781022320156">Kiwango cha sera hakitumiki.</translation>
<translation id="6915804003454593391">Mtumiaji:</translation>
+<translation id="6957887021205513506">Cheti cha seva kinaonekana kuwa ghushi.</translation>
<translation id="6965382102122355670">Sawa</translation>
<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="6980028882292583085">Arifa ya Javascript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Ulijaribu kufikia <ph name="DOMAIN" />, lakini seva ikawasilisha cheti ambacho muda wake sahihi ni mrefu sana wa kuweza kuaminika.</translation>
<translation id="7087282848513945231">Nchi</translation>
-<translation id="7108649287766967076">Tafsiri kwenda <ph name="TARGET_LANGUAGE"/> imeshindwa.</translation>
+<translation id="7108649287766967076">Tafsiri kwenda <ph name="TARGET_LANGUAGE" /> imeshindwa.</translation>
<translation id="7139724024395191329">Emirate</translation>
+<translation id="7179921470347911571">Zindua upya Sasa</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="7186367841673660872">Ukurasa huu umetafsiriwa kutoka<ph name="ORIGINAL_LANGUAGE" />hadi<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Tafuta <ph name="SITE_NAME"/> kupata <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Tafuta <ph name="SITE_NAME" /> kupata <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Muunganisho wa faragha kwenye <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hauwezi kutambuliwa kwa sababu tarehe na wakati wa kompyuta yako (<ph name="DATE_AND_TIME" />) si sahihi.</translation>
<translation id="7275334191706090484">Alamisho Zinazosimamiwa</translation>
<translation id="7298195798382681320">Zinazopendekezwa</translation>
<translation id="7334320624316649418">Rudia Kupanga Upya</translation>
@@ -205,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Lazima</translation>
<translation id="7542995811387359312">Mjazo otomatiki wa kadi ya mkopo umelemazwa kwa sababu fomu hii haitumii muunganisho salama.</translation>
-<translation id="7568593326407688803">Ukurasa huu umeandikwa kwa<ph name="ORIGINAL_LANGUAGE"/>Je, ungependa kuutafsiri?</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="7568593326407688803">Ukurasa huu umeandikwa kwa<ph name="ORIGINAL_LANGUAGE" />Je, ungependa kuutafsiri?</translation>
<translation id="7569952961197462199">Ungependa kuondoa kadi ya malipo kutoka kwenye Chrome?</translation>
-<translation id="7600965453749440009">Kamwe usitafsiri <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Thamani imezidi masafa<ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Cheti cha seva kinakiuka vikwazo vya jina.</translation>
+<translation id="7600965453749440009">Kamwe usitafsiri <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Thamani imezidi masafa<ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Unavutiwa na vipengee vipya vizuri vya Chrome? Jaribu kituo chetu cha dev katika chrome.com/dev.</translation>
<translation id="7752995774971033316">Haidhibitiwi</translation>
+<translation id="7761701407923456692">Cheti cha seva hakilingani na URL.</translation>
<translation id="777702478322588152">Wilaya</translation>
<translation id="7791543448312431591">Ongeza</translation>
<translation id="7805768142964895445">Hali</translation>
<translation id="7813600968533626083">Ungependa kuondoa pendekezo la fomu kutoka kwenye Chrome?</translation>
<translation id="7887683347370398519">Angalia CVC yako na ujaribu tena</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Cheti cha seva bado sio halali.</translation>
<translation id="7956713633345437162">Alamisho kwenye simu</translation>
<translation id="7961015016161918242">Katu</translation>
<translation id="7977590112176369853">&lt;weka hoja&gt;</translation>
-<translation id="7983301409776629893">Tafsiri kutoka <ph name="ORIGINAL_LANGUAGE"/> hadi <ph name="TARGET_LANGUAGE"/> kila wakati</translation>
+<translation id="7983301409776629893">Tafsiri kutoka <ph name="ORIGINAL_LANGUAGE" /> hadi <ph name="TARGET_LANGUAGE" /> kila wakati</translation>
<translation id="7988324688042446538">Alamisho za eneokazi</translation>
<translation id="7995512525968007366">Hakijabainishwa</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="8003882219468422867">Batilisha biashara</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="8088680233425245692">Haikufaulu kuangalia makala.</translation>
<translation id="8091372947890762290">Uwashaji unasubiri kwenye seva</translation>
<translation id="8194797478851900357">Tendua hatua</translation>
-<translation id="8201077131113104583">URL ya sasisho si sahihi kwa kiendelezi chenye Kitambulisho &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">URL ya sasisho si sahihi kwa kiendelezi chenye Kitambulisho "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Usihifadhi</translation>
<translation id="8218327578424803826">Mahali Palipohawilishwa:</translation>
<translation id="8249320324621329438">Iliyoletwa mwisho:</translation>
+<translation id="8294431847097064396">Chanzo</translation>
<translation id="8308427013383895095">Utafsiri haukufanikiwa kwa sababu ya hitilafu ya seva.</translation>
<translation id="8311778656528046050">Je, una uhakika kuwa unataka kuupakia upya ukurasa huu?</translation>
<translation id="8349305172487531364">Sehemu ya Alamisho</translation>
@@ -238,25 +303,40 @@
<translation id="8488350697529856933">Inatumika kwenye</translation>
<translation id="8530504477309582336">Aina hii ya kadi haiwezi kutumiwa na Google Payments. Tafadhali teua kadi tofauti.</translation>
<translation id="8553075262323480129">Tafsiri imeshindwa kwa sababu lugha ya ukurasa isingeweza kuthibitishwa.</translation>
-<translation id="8571890674111243710">Inatafsiri ukurasa katika <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Muunganisho wa faragha kwenye <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hauwezi kupatikana kwa sababu tarehe na wakati wa kifaa chako (<ph name="DATE_AND_TIME" />) si sahihi.</translation>
+<translation id="8571890674111243710">Inatafsiri ukurasa katika <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Weka upya zote kwa chaguo-msingi</translation>
<translation id="8713130696108419660">Sahihi mbaya ya mwanzo</translation>
<translation id="8725066075913043281">Jaribu tena</translation>
+<translation id="8738058698779197622">Ili kutambua muunganisho salama, saa yako inahitaji kuwekwa sahihi. Hii ni kwa sababu vyeti ambavyo tovuti hutumia kujitambua ni sahihi kwa vipindi mahususi pekee. Kwa kuwa saa ya kifaa chako si sahihi, Chromium haiwezi kuthibitisha vyeti hivi.</translation>
<translation id="8790007591277257123">Rudia kufuta</translation>
<translation id="8804164990146287819">Sera ya Faragha</translation>
+<translation id="8820817407110198400">Alamisho</translation>
<translation id="8824019021993735287">Chrome haikuthibitisha kadi yako wakati huu. Tafadhali jaribu tena baadaye.</translation>
<translation id="8834246243508017242">Washa Kujaza Otomatiki ukitumia Anwani…</translation>
<translation id="883848425547221593">Alamisho Zingine</translation>
+<translation id="884923133447025588">Mbinu ya ubatilishaji haikupatikana.</translation>
<translation id="8866481888320382733">Hitilafu wakati wa kuchanganua mipangilio ya sera</translation>
<translation id="8876793034577346603">Usanidi wa mtandao umekosa kuchanganuliwa.</translation>
<translation id="8891727572606052622">Modi batili ya proksi.</translation>
-<translation id="8940229512486821554">Endesha amri ya <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Samahani, jaribio hili halipatikani kwenye mfumo wako wa uendeshaji.</translation>
+<translation id="8903921497873541725">Kuza karibu</translation>
+<translation id="8932102934695377596">Saa yako iko nyuma</translation>
+<translation id="8940229512486821554">Endesha amri ya <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Cheti cha seva kimechina.</translation>
<translation id="8988760548304185580">Weka tarehe kuisha muda na CVC yenye tarakimu 3 kutoka nyuma ya kadi yako</translation>
-<translation id="9020542370529661692">Ukurasa huu umetafsiriwa kwenda <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Alama zinazotumika katika mfumo mzima zinaweza kuwekwa na mmiliki pekee: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Ukurasa huu umetafsiriwa kwenda <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Ulijaribu kufikia <ph name="DOMAIN" />, lakini seva iliwasilisha cheti batili.</translation>
<translation id="9125941078353557812">Weka CVC yenye tarakimu 3 kutoka nyuma ya kadi yako</translation>
<translation id="9137013805542155359">Onyesha asili</translation>
<translation id="9148507642005240123">Tendua kuhariri</translation>
<translation id="9154176715500758432">Kaa kwenye Ukurasa huu</translation>
<translation id="9170848237812810038">&amp;Tendua</translation>
+<translation id="917450738466192189">Cheti cha seva ni batili.</translation>
+<translation id="9187827965378254003">Lo, inaonekana kuwa hakuna majaribio yanayopatikana.</translation>
<translation id="9207861905230894330">Haikufaulu kuongeza makala.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">FUTA FOMU</translation>
+<translation id="988159990683914416">Muundo wa Wasanidi Programu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ta.xtb b/chromium/components/strings/components_strings_ta.xtb
index 6bb5f8fbeb6..349e0e467f1 100644
--- a/chromium/components/strings/components_strings_ta.xtb
+++ b/chromium/components/strings/components_strings_ta.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="ta">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ta">
+<translation id="1032854598605920125">கடிகாரத்திசையில் சுழற்று</translation>
<translation id="1055184225775184556">&amp;சேர்த்தலைச் செயல்தவிர்</translation>
<translation id="106701514854093668">டெஸ்க்டாப் புக்மார்க்குகள்</translation>
-<translation id="1103523840287552314">எப்போதும் இந்த மொழியை மொழிபெயர் <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">அகலத்திற்குப் பொருத்து</translation>
+<translation id="1103523840287552314">எப்போதும் இந்த மொழியை மொழிபெயர் <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;மறுவரிசைப்படுத்தலைச் செயல்தவிர்</translation>
<translation id="111844081046043029">இந்த பக்கத்தை விட்டு நிச்சயமாக வெளியேற வேண்டுமா?</translation>
<translation id="112840717907525620">கொள்கை தற்காலிக சேமிப்பு சரியாக உள்ளது</translation>
<translation id="1132774398110320017">Chrome தன்னிரப்பி அமைப்புகள்...</translation>
-<translation id="1152921474424827756"><ph name="URL"/> இன் <ph name="BEGIN_LINK"/>உருவாக்கத்திற்கான தற்காலிகச் சேமிப்பு நகலை<ph name="END_LINK"/> அணுகவும்</translation>
+<translation id="1150979032973867961">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழை உங்கள் கணினியின் இயக்க முறைமை நம்பவில்லை. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
+<translation id="1152921474424827756"><ph name="URL" /> இன் <ph name="BEGIN_LINK" />உருவாக்கத்திற்கான தற்காலிகச் சேமிப்பு நகலை<ph name="END_LINK" /> அணுகவும்</translation>
+<translation id="121201262018556460">நீங்கள் <ph name="DOMAIN" /> ஐ அடைய முயற்சித்தீர்கள் ஆனால் சேவையகம் ஒரு வலுவற்ற விசை கொண்ட சான்றிதழை வழங்கியது. தனிப்பட்ட விசையை தீங்கிழைப்பவர் களவாடி இருப்பதால், சேவையகம் நீங்கள் எதிர்பார்த்த (தீங்கிழைப்பவருடன் நீங்கள் தகவல் பரிமாற்றம் செய்துகொண்டிருக்கலாம்) சேவையகமாக இல்லாமல் இருக்கலாம்.</translation>
<translation id="1227224963052638717">அறியாத கொள்கை.</translation>
<translation id="1227633850867390598">மதிப்பை மறை</translation>
<translation id="1228893227497259893">தவறான உட்பொருள் அடையாளங்காட்டி</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">பதிவுக் களம்:</translation>
<translation id="1344588688991793829">Chromium தன்னிரப்பி அமைப்புகள்...</translation>
<translation id="1426410128494586442">ஆம்</translation>
+<translation id="1430915738399379752">அச்சிடுக</translation>
<translation id="1455235771979731432">கார்டைப் புதுப்பிப்பதில் சிக்கல். இணைய இணைப்பைச் சரிபார்த்து, மீண்டும் முயற்சிக்கவும்.</translation>
<translation id="1491151370853475546">இந்தப் பக்கத்தை மீண்டும் ஏற்று</translation>
<translation id="1549470594296187301">இந்த அம்சத்தைப் பயன்படுத்த JavaScript இயக்கப்பட வேண்டும்.</translation>
-<translation id="1639239467298939599">ஏற்றுகிறது</translation>
<translation id="1640180200866533862">பயனர் கொள்கைகள்</translation>
<translation id="1644184664548287040">பிணைய உள்ளமைவு தவறானது மேலும் அதை இறக்குமதி செய்ய முடியவில்லை.</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> இல் உள்ள பக்கம் கூறுவது:</translation>
+<translation id="1655462015569774233">{1,plural, =1{இந்தச் சேவையகம் தான் <ph name="DOMAIN" /> என்பதை நிரூபிக்க முடியவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் நேற்று காலாவதியானது. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம். உங்கள் கணினியின் கடிகாரம் தற்போது <ph name="CURRENT_DATE" /> என அமைக்கப்பட்டுள்ளது. அது சரியாக இருக்கிறதா? இல்லை என்றால், உங்கள் முறைமையின் கடிகாரத்தைச் சரிசெய்து, பின்னர் இந்தப் பக்கத்தைப் புதுப்பிக்க வேண்டும்.}other{இந்தச் சேவையகம் தான் <ph name="DOMAIN" /> என்பதை நிரூபிக்க முடியவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் # நாட்களுக்கு முன்பு காலாவதியானது. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம். உங்கள் கணினியின் கடிகாரம் தற்போது <ph name="CURRENT_DATE" /> என அமைக்கப்பட்டுள்ளது. அது சரியாக இருக்கிறதா? இல்லை என்றால், உங்கள் முறைமையின் கடிகாரத்தைச் சரிசெய்து, பின்னர் இந்தப் பக்கத்தைப் புதுப்பிக்க வேண்டும்.}}</translation>
+<translation id="168841957122794586">சேவையக சான்றிதழில் வலுவற்ற குறியீட்டாக்க விசை இருக்கிறது.</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> இல் உள்ள பக்கம் கூறுவது:</translation>
+<translation id="1706954506755087368">{1,plural, =1{இந்தச் சேவையகம் தான் <ph name="DOMAIN" /> என்பதை நிரூபிக்க முடியவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் நாளை முதலே செல்லுபடியாகும். இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.}other{இந்தச் சேவையகம் தான் <ph name="DOMAIN" /> என்பதை நிரூபிக்க முடியவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் எதிர்காலத்தில் # நாட்களில் ஏற்றுக்கொள்ளப்படும். இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழை உங்கள் சாதனத்தின் இயக்க முறைமை நம்பவில்லை. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
<translation id="1821930232296380041">தவறான கோரிக்கை அல்லது கோரிக்கை அளவுருக்கள்</translation>
-<translation id="1853748787962613237">கட்டுரையைக் காண்பிப்பதில் தோல்வி.</translation>
<translation id="1871208020102129563">நிலையான ப்ராக்ஸி சேவையகங்களைப் பயன்படுத்த ப்ராக்ஸி அமைக்கப்பட்டுள்ளது, .pac ஸ்கிரிப்ட் URL அல்ல.</translation>
-<translation id="1875753206475436906">சூத்திர வகை: <ph name="HEURISTIC_TYPE"/>
- சேவையக வகை: <ph name="SERVER_TYPE"/>
- புல கையொப்பம்: <ph name="FIELD_SIGNATURE"/>
- படிவ கையொப்பம்: <ph name="FORM_SIGNATURE"/>
- சோதனை ஐடி: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158"><ph name="LINK"/> க்குச் செல்க</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> புத்தகக்குறிகள்</translation>
+<translation id="194030505837763158"><ph name="LINK" /> க்குச் செல்க</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> புத்தகக்குறிகள்</translation>
<translation id="1973335181906896915">தொடராக்க பிழை</translation>
+<translation id="1974060860693918893">மேம்பட்டவை</translation>
<translation id="2025186561304664664">ப்ராக்ஸி, தானியங்கி உள்ளமைவுக்கு அமைக்கப்பட்டுள்ளது</translation>
<translation id="2025623846716345241">மீண்டும் ஏற்றுவதை உறுதிபடுத்தவும்</translation>
-<translation id="2030481566774242610"><ph name="LINK"/> ஐக் குறிப்பிடுகிறீர்களா?</translation>
+<translation id="2030481566774242610"><ph name="LINK" /> ஐக் குறிப்பிடுகிறீர்களா?</translation>
<translation id="2053553514270667976">ஜிப் குறியீடு</translation>
<translation id="20817612488360358">கணினி ப்ராக்ஸி அமைப்புகள் பயன்படுத்த அமைக்கப்பட்டுள்ளது. வெளிப்படையான ப்ராக்ஸி உள்ளமைவும் குறிப்பிடப்பட்டுள்ளது.</translation>
<translation id="2094505752054353250">டொமைன் பொருந்தவில்லை</translation>
<translation id="2096368010154057602">துறை</translation>
<translation id="2113977810652731515">கார்டு</translation>
-<translation id="2114841414352855701"><ph name="POLICY_NAME"/> ஆல் கொள்கை மேலெழுதப்பட்டுள்ளதால் புறக்கணிக்கப்பட்டது.</translation>
+<translation id="2114841414352855701"><ph name="POLICY_NAME" /> ஆல் கொள்கை மேலெழுதப்பட்டுள்ளதால் புறக்கணிக்கப்பட்டது.</translation>
+<translation id="2128531968068887769">நேட்டிவ் கிளையன்ட்</translation>
<translation id="213826338245044447">மொபைல் புக்மார்க்குகள்</translation>
+<translation id="2171101176734966184"><ph name="DOMAIN" /> ஐ அடைய முயற்சி செய்தீர்கள். ஆனால் வலிமையற்ற கையொப்ப அல்காரிதமைப் பயன்படுத்தி கையொப்பமிடப்பட்ட சான்றிதழை சேவையகம் வழங்கியது. அதாவது, சேவையகம் வழங்கிய பாதுகாப்பு நம்பிக்கைச்சான்றுகள் போலியானதாக்கப்பட்டிருக்கலாம் மேலும் நீங்கள் எதிர்பார்த்த (போலியான ஒன்றுடன் நீங்கள் தகவல் பரிமாற்றம் செய்திருக்கக்கூடும்) சேவையகமாக அந்த சேவையகம் இல்லாமலிருக்கலாம்.</translation>
<translation id="2181821976797666341">கொள்கைகள்</translation>
<translation id="2212735316055980242">கொள்கை காணப்படவில்லை</translation>
<translation id="2213606439339815911">உள்ளீடுகளைப் பெறுகிறது...</translation>
<translation id="225207911366869382">இந்த கொள்கைக்கான மதிப்பு தடுக்கப்பட்டது.</translation>
<translation id="2262243747453050782">HTTP பிழை</translation>
-<translation id="2270192940992995399">கட்டுரையைக் கண்டறிவதில் தோல்வி.</translation>
-<translation id="2328300916057834155"><ph name="ENTRY_INDEX"/> அட்டவணையில் தவறான புக்மார்க் புறக்கணிக்கப்பட்டது</translation>
+<translation id="2282872951544483773">கிடைக்காத பரிசோதனைகள்</translation>
+<translation id="229702904922032456">ரூட் அல்லது இன்டர்மீடியட் சான்றிதழ் காலாவதியானது.</translation>
+<translation id="2328300916057834155"><ph name="ENTRY_INDEX" /> அட்டவணையில் தவறான புக்மார்க் புறக்கணிக்கப்பட்டது</translation>
<translation id="2354001756790975382">பிற புக்மார்க்ஸ்</translation>
<translation id="2359808026110333948">தொடர்க</translation>
<translation id="2367567093518048410">நிலை</translation>
+<translation id="2384307209577226199">நிறுவன இயல்புநிலை</translation>
+<translation id="2386255080630008482">சேவையகச் சான்றிதழ் திரும்பப் பெறப்பட்டது.</translation>
<translation id="2392959068659972793">மதிப்பும் எதுவும் அமைக்கப்படாத கொள்கைகளைக் காட்டு</translation>
<translation id="2396249848217231973">&amp;நீக்குதலைச் செயல்தவிர்</translation>
+<translation id="2413528052993050574">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் திரும்பப்பெறப்பட்டிருக்கலாம். இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
<translation id="2455981314101692989">இந்தப் படிவத்திற்கான தானியங்கு நிரப்புதலை இந்த வலைப்பக்கம் முடக்கியுள்ளது.</translation>
<translation id="2479410451996844060">தவறான தேடல் URL.</translation>
+<translation id="2491120439723279231">சேவையகச் சான்றிதழில் பிழைகள் உள்ளன.</translation>
<translation id="2495083838625180221">JSON பார்சர்</translation>
<translation id="2498091847651709837">புதிய கார்டை ஸ்கேன்செய்</translation>
<translation id="2556876185419854533">&amp;திருத்தலைச் செயல்தவிர்</translation>
-<translation id="2581221116934462656">அடுத்த முறை இந்தத் தளத்திலிருந்து <ph name="LANGUAGE_NAME"/> பக்கங்களுக்கான மொழிப்பெயர்ப்பை <ph name="PRODUCT_NAME"/> வழங்குவதை விரும்புகிறீர்களா?</translation>
+<translation id="2581221116934462656">அடுத்த முறை இந்தத் தளத்திலிருந்து <ph name="LANGUAGE_NAME" /> பக்கங்களுக்கான மொழிப்பெயர்ப்பை <ph name="PRODUCT_NAME" /> வழங்குவதை விரும்புகிறீர்களா?</translation>
<translation id="2587841377698384444">கோப்பக API ஐடி:</translation>
<translation id="2597378329261239068">இந்த ஆவணம் கடவுச்சொல் பாதுகாக்கப்பட்ட ஒன்று. தயவுசெய்து ஒரு கடவுச்சொல்லை உள்ளிடுக.</translation>
+<translation id="2625385379895617796">உங்கள் கடிகாரம் மிகவும் முன்னோக்கி இருக்கிறது</translation>
<translation id="2639739919103226564">நிலை:</translation>
+<translation id="2653659639078652383">சமர்ப்பி</translation>
<translation id="2704283930420550640">மதிப்பானது வடிவமைப்பிற்குப் பொருந்தவில்லை.</translation>
<translation id="2721148159707890343">கோரிக்கை வெற்றி</translation>
+<translation id="2728127805433021124">சேவையகச் சான்றிதழ் ஒரு வலுவற்ற கையொப்ப அல்காரிதமைப் பயன்படுத்தி கையொப்பமிடப்பட்டுள்ளது.</translation>
<translation id="2774256287122201187">தொடரலாம். அப்படி தொடர்ந்தால், ஐந்து நிமிடங்களுக்கு இந்த எச்சரிக்கை மீண்டும் காட்டப்படாது.</translation>
<translation id="277499241957683684">சாதனப் பதிவு இல்லை</translation>
<translation id="2835170189407361413">படிவத்தை அழி</translation>
-<translation id="2855922900409897335">உங்கள் <ph name="CREDIT_CARD"/> கார்டைச் சரிபார்க்கவும்</translation>
+<translation id="2855922900409897335">உங்கள் <ph name="CREDIT_CARD" /> கார்டைச் சரிபார்க்கவும்</translation>
+<translation id="2915500479781995473">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் காலாவதியாகிவிட்டது. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம். உங்கள் கணினியின் கடிகாரம் இப்போது <ph name="CURRENT_TIME" />க்கு அமைக்கப்பட்டுள்ளது. இது சரியாக உள்ளதா? தவறு எனில், உங்கள் கணினியின் கடிகாரத்தைச் சரிசெய்து, இந்தப் பக்கத்தைப் புதுப்பிக்கவும்.</translation>
+<translation id="2922350208395188000">சேவையகச் சான்றிதழை சோதிக்க முடியவில்லை.</translation>
+<translation id="2941952326391522266">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் <ph name="DOMAIN2" /> இலிருந்து பெறப்பட்டது. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
<translation id="2958431318199492670">பிணைய உள்ளமைப்பானது ONC தரத்துடன் இணங்கவில்லை. உள்ளமைவின் பகுதிகள் இறக்குமதியாகாமல் போகக்கூடும்.</translation>
<translation id="2972581237482394796">&amp;மீண்டும் செய்</translation>
-<translation id="3010559122411665027">பட்டியல் உள்ளீடு &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">பட்டியல் உள்ளீடு "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">தவறான கொள்கை வகை</translation>
<translation id="3105172416063519923">பண்பு ஐடி:</translation>
<translation id="3145945101586104090">பதிலைக் குறிநீக்கம் செய்வதில் தோல்வி</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">தீவு</translation>
<translation id="3219579145727097045">கார்டின் முன்புறமுள்ள காலாவதி தேதி மற்றும் நான்கு இலக்க CVCஐ உள்ளிடவும்</translation>
-<translation id="3228969707346345236">பக்கம் முன்பே <ph name="LANGUAGE"/> இல் இருப்பதால் மொழிபெயர்ப்பு தோல்வியடைந்தது.</translation>
+<translation id="3225919329040284222">உள்ளமைந்த எதிர்பார்ப்புகளுடன் பொருந்தாத சான்றிதழை சேவையகம் வழங்கியது. சில உயர்-பாதுகாப்பு வலைத்தளங்களில் உங்களைப் பாதுகாக்கவே இந்த எதிர்பார்ப்புகள் சேர்க்கப்படுகின்றன.</translation>
+<translation id="3228969707346345236">பக்கம் முன்பே <ph name="LANGUAGE" /> இல் இருப்பதால் மொழிபெயர்ப்பு தோல்வியடைந்தது.</translation>
<translation id="3270847123878663523">&amp;மறுவரிசைப்படுத்தலைச் செயல்தவிர்</translation>
+<translation id="3286538390144397061">இப்போது மறுதொடக்கம் செய்க</translation>
<translation id="333371639341676808">இந்த பக்கம் கூடுதல் உரையாடல்களை உருவாக்குவதைத் தடு.</translation>
-<translation id="3369366829301677151"><ph name="CREDIT_CARD"/>ஐப் புதுப்பித்து, சரிபார்க்கவும்</translation>
+<translation id="3340978935015468852">அமைப்புகள்</translation>
+<translation id="3369192424181595722">கடிகாரப் பிழை</translation>
+<translation id="3369366829301677151"><ph name="CREDIT_CARD" />ஐப் புதுப்பித்து, சரிபார்க்கவும்</translation>
<translation id="337363190475750230">விடுவித்தது</translation>
<translation id="3377188786107721145">கொள்கையை அலசுவதில் பிழை</translation>
<translation id="3380365263193509176">அறியப்படாத பிழை</translation>
<translation id="3380864720620200369">கிளையன்ட் ஐடி:</translation>
<translation id="3427342743765426898">&amp;திருத்தலை மீண்டும் செய்</translation>
+<translation id="3435896845095436175">இயக்கு</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">எடுப்பதற்கான இடைவேளை:</translation>
+<translation id="3462200631372590220">மேம்பட்டவையை மறை</translation>
+<translation id="3528171143076753409">சேவையகச் சான்றிதழ் நம்பப்படவில்லை.</translation>
<translation id="3542684924769048008">இதற்காக கடவுச்சொல்லைப் பயன்படுத்தவும்:</translation>
<translation id="3583757800736429874">&amp;நகர்த்தலை மீண்டும் செய்</translation>
<translation id="3623476034248543066">மதிப்பைக் காட்டு</translation>
+<translation id="3648607100222897006">இந்தச் சோதனை அம்சங்கள், எப்போது வேண்டுமானாலும் மாறலாம், துண்டிக்கப்படலாம் அல்லது மறைந்து விடலாம். இந்த அம்சங்களில் ஏதேனும் ஒன்றை நீங்கள் இயக்குவதால் ஏற்படும் நிகழ்வுகளுக்கு நாங்கள் எவ்வகையிலும் எந்தவித உத்தரவாதமும் அளிக்கவில்லை. மேலும் உங்கள் உலாவியானது திடீரென்று செயலிழந்து விடக்கூடும். உண்மையில் உங்கள் உலாவியின் தரவு அனைத்தையும் நீக்கவிடலாம் அல்லது உங்கள் பாதுகாப்பு, தனியுரிமையானது எதிர்பாராத வழிகளில் மாற்றியமைக்கப்படலாம். நீங்கள் செயல்படுத்தும் எந்த சோதனைகளும் இந்த உலாவியின் எல்லா பயனர்களுக்கும் செயல்படுத்தப்படும். எச்சரிக்கையாகத் தொடர்க.</translation>
<translation id="3650584904733503804">சரிபார்ப்பு வெற்றி</translation>
<translation id="370665806235115550">நினைவேறுகிறது...</translation>
<translation id="3712624925041724820">உரிமம் முடிந்தது</translation>
<translation id="3739623965217189342">நீங்கள் நகலெடுத்த இணைப்பு</translation>
<translation id="375403751935624634">ஒரு சேவையகப் பிழையின் காரணமாக மொழிபெயர்ப்புத் தோல்வியடைந்தது.</translation>
<translation id="385051799172605136">முந்தைய பக்கம்</translation>
+<translation id="3858027520442213535">தேதியையும் நேரத்தையும் புதுப்பி</translation>
<translation id="3884278016824448484">முரண்பாடான சாதன அடையாளங்காட்டி</translation>
<translation id="3885155851504623709">வட்டாரம்</translation>
<translation id="3934680773876859118">PDF ஆவணத்தை ஏற்றுவது தோல்வியடைந்தது</translation>
<translation id="3963721102035795474">படித்தல் பயன்முறை</translation>
<translation id="4030383055268325496">&amp;சேர்த்தலைச் செயல்தவிர்</translation>
-<translation id="4058922952496707368">விசை &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">எச்சரிக்கை</translation>
+<translation id="4058922952496707368">விசை "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">ப்ராக்ஸி உள்ளமைவானது, .pac ஸ்கிரிப்ட் URL ஐப் பயன்படுத்தும்படி அமைக்கப்பட்டிருக்கிறது, நிலையான ப்ராக்ஸி சேவையகங்களுக்கு அல்ல.</translation>
<translation id="409504436206021213">மீண்டும் ஏற்ற வேண்டாம்</translation>
<translation id="4103249731201008433">சாதன சீரியல் எண் தவறானது</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">தவறான கையொப்பம்</translation>
<translation id="4269787794583293679">(பயனர்பெயர் இல்லை)</translation>
<translation id="4300246636397505754">மூலப் பரிந்துரைகள்</translation>
-<translation id="4372948949327679948">எதிர்பார்த்த <ph name="VALUE_TYPE"/> மதிப்பு.</translation>
+<translation id="4325863107915753736">கட்டுரையைக் கண்டறிய முடியவில்லை</translation>
+<translation id="4372948949327679948">எதிர்பார்த்த <ph name="VALUE_TYPE" /> மதிப்பு.</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" /> ஐ அடைய முயற்சி செய்தீர்கள். ஆனால் சேவையகம் வழங்கிய சான்றிதழானது அதன் வழங்குநரால் நிராகரிக்கப்பட்டது. அதாவது, சேவையகம் வழங்கிய பாதுகாப்பு நம்பிக்கைச்சான்றுகளை நிச்சயமாக எக்காரணத்தைக்கொண்டும் நம்பக்கூடாது. போலியான ஒன்றுடன் நீங்கள் தகவல் பரிமாற்றம் செய்துகொண்டிருக்கக்கூடும்.</translation>
+<translation id="4394049700291259645">முடக்கு</translation>
+<translation id="4424024547088906515">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழை Chrome நம்பவில்லை. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
<translation id="443673843213245140">ப்ராக்ஸி பயன்பாடு முடக்கப்பட்டுள்ளது. ஆனால் வெளிப்படையான ப்ராக்ஸி உள்ளமைவு குறிப்பிடப்பட்டுள்ளது.</translation>
-<translation id="4506176782989081258">சரிபார்ப்புப் பிழை: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">சரிபார்ப்புப் பிழை: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chrome இலிருந்து முகவரியை அகற்றவா?</translation>
<translation id="4594403342090139922">&amp;நீக்குதலைச் செயல்தவிர்</translation>
<translation id="4607653538520819196">இந்தப் பக்கத்தைத் தரவு சேமிப்பானால் ப்ராக்ஸி செய்ய முடியாது.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழில் பிழைகள் உள்ளன. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
<translation id="4726672564094551039">கொள்கைகளை மீண்டும் ஏற்று</translation>
+<translation id="4728558894243024398">ப்ளாட்ஃபார்ம்</translation>
+<translation id="4771973620359291008">அறியப்படாத பிழை ஏற்பட்டுள்ளது.</translation>
<translation id="4800132727771399293">காலாவதியாகும் நேரத்தையும், CVCஐயும் சரிபார்த்து, மீண்டும் முயற்சிக்கவும்</translation>
<translation id="4813512666221746211">பிணைய பிழை</translation>
+<translation id="4816492930507672669">பக்கத்தில் பொருத்து</translation>
<translation id="4850886885716139402">காட்சி</translation>
-<translation id="4923417429809017348">ஒரு அறியப்படாத மொழியிலிருந்து <ph name="LANGUAGE_LANGUAGE"/> -க்கு இந்தப் பக்கம் மொழிபெயர்க்கப்பட்டுள்ளது</translation>
+<translation id="4923417429809017348">ஒரு அறியப்படாத மொழியிலிருந்து <ph name="LANGUAGE_LANGUAGE" /> -க்கு இந்தப் பக்கம் மொழிபெயர்க்கப்பட்டுள்ளது</translation>
<translation id="4926049483395192435">கட்டாயம் குறிப்பிட வேண்டும்.</translation>
<translation id="4968547170521245791">ப்ராக்ஸி செய்ய முடியாது</translation>
-<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE"/> இலிருந்து <ph name="TARGET_LANGUAGE"/> க்கு மொழிபெயர்க்கவா?</translation>
+<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE" /> இலிருந்து <ph name="TARGET_LANGUAGE" /> க்கு மொழிபெயர்க்கவா?</translation>
<translation id="5019198164206649151">தவறான நிலையில் மீட்பு சேமிப்பு உள்ளது</translation>
<translation id="5031870354684148875">Google மொழியாக்கம் ஓர் அறிமுகம்</translation>
+<translation id="5045550434625856497">தவறான கடவுச்சொல்</translation>
+<translation id="5087286274860437796">தற்போது சேவையகத்தின் சான்றிதழ் செல்லுபடியாகாது.</translation>
<translation id="5089810972385038852">மாநிலம்</translation>
+<translation id="5094747076828555589">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழை Chromium நம்பவில்லை. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
<translation id="5095208057601539847">பிராந்தியம்</translation>
<translation id="5145883236150621069">கொள்கைப் பதிலில் பிழைக் குறியீடு உள்ளது</translation>
<translation id="5172758083709347301">இயந்திரம்</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/> இல் இல்லையா? இந்தப் பிழையை தெரிவிக்கவும்</translation>
+<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> இல் இல்லையா? இந்தப் பிழையை தெரிவிக்கவும்</translation>
<translation id="5190835502935405962">புக்மார்க்குகள் பட்டி</translation>
+<translation id="5199729219167945352">சோதனைகள்</translation>
+<translation id="5251803541071282808">மேகக்கணி</translation>
<translation id="5295309862264981122">வழிசெலுத்துதலை உறுதிசெய்க</translation>
<translation id="5299298092464848405">கொள்கையை அலசுவதில் பிழை</translation>
+<translation id="5316812925700871227">கடிகார எதிர்த்திசையில் சுழற்று</translation>
<translation id="5317780077021120954">சேமி</translation>
<translation id="536296301121032821">கொள்கை அமைப்புகளைச் சேமிப்பதில் தோல்வி</translation>
-<translation id="5439770059721715174">&quot;<ph name="ERROR_PATH"/>&quot; திட்டமுறை சரிபார்ப்புப் பிழை: <ph name="ERROR"/></translation>
+<translation id="540969355065856584"><ph name="DOMAIN" /> டொமைனை, சேவையகம் உறுதிப்படுத்தவில்லை; அதற்கான காரணங்கள்: இதன் பாதுகாப்புச் சான்றிதழ் தற்போது செல்லுபடியானதல்ல. இது தவறான உள்ளமைவினால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
+<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" திட்டமுறை சரிபார்ப்புப் பிழை: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">தவறான கொள்கை நேரமுத்திரை</translation>
<translation id="5470861586879999274">&amp;திருத்தலை மீண்டும் செய்</translation>
<translation id="5509780412636533143">நிர்வகிக்கப்படும் புக்மார்க்குகள்</translation>
<translation id="5523118979700054094">கொள்கைப் பெயர்</translation>
<translation id="552553974213252141">உரையானது சரியான முறையில் பிரித்தெடுக்கப்பட்டதா?</translation>
<translation id="5540224163453853">கோரப்பட்ட கட்டுரையைக் கண்டுபிடிக்க முடியவில்லை.</translation>
+<translation id="5556459405103347317">மீண்டும் ஏற்று</translation>
<translation id="5565735124758917034">செயலில் உள்ளது</translation>
<translation id="560412284261940334">நிர்வாகம் ஆதரிக்கவில்லை</translation>
<translation id="5629630648637658800">கொள்கை அமைப்புகளை ஏற்றுவதில் தோல்வி</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">நடப்புப் பயனர்</translation>
<translation id="5813119285467412249">&amp;சேர்த்தலை மீண்டும் செய்</translation>
<translation id="5872918882028971132">மூலப் பரிந்துரைகள்</translation>
-<translation id="587701087903783706">மொபைலுக்கு ஏற்ற காட்சியை மூடவும்</translation>
<translation id="59107663811261420">இந்த வியாபாரிக்கு Google Payments இல் இந்த வகையான கார்டு ஆதரிக்கப்படாது. வேறொரு கார்டைத் தேர்ந்தெடுக்கவும்.</translation>
+<translation id="5975083100439434680">சிறிதாக்கு</translation>
<translation id="5989320800837274978">ப்ராக்ஸி சேவையகம் சரிசெய்யப்படவும் இல்லை .pac ஸ்கிரிப்ட் URL குறிப்பிடப்படவுமில்லை.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">மூடு</translation>
+<translation id="6060685159320643512">கவனம், இந்த சோதனைகள் பாதிப்பை ஏற்படுத்தலாம்</translation>
+<translation id="6151417162996330722">சேவை சான்றிதழ் நீண்ட செல்லுபடிக் காலத்தைக் கொண்டுள்ளது.</translation>
<translation id="6154808779448689242">கிடைத்த கொள்கை டோக்கன், தற்போதுள்ள டோக்கனுடன் பொருந்தவில்லை</translation>
<translation id="6165508094623778733">மேலும் அறிக</translation>
<translation id="6259156558325130047">&amp;மறுவரிசைப்படுத்தலை மீண்டும் செய்</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> புக்மார்க்குகள்</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> புக்மார்க்குகள்</translation>
<translation id="6282194474023008486">அஞ்சல் குறியீடு</translation>
<translation id="6337534724793800597">பெயரின்படி கொள்கைகளை வடி</translation>
+<translation id="6387478394221739770">புதிய Chrome அம்சங்களில் ஆர்வம் உள்ளதா? chrome.com/beta இல் எங்களுடைய பீட்டா அலைவரிசையை முயற்சிக்கவும்.</translation>
+<translation id="6426993025560594914">எல்லா பரிசோதனைகளும் உங்கள் இயங்குதளத்தில் கிடைக்கின்றன!</translation>
<translation id="6445051938772793705">நாடு</translation>
<translation id="6458467102616083041">கொள்கை மூலம் இயல்புநிலை தேடல் முடக்கப்பட்டுள்ளதால், பாலிசியின் மதிப்பு புறக்கணிக்கப்பட்டுள்ளது.</translation>
<translation id="647261751007945333">சாதனக் கொள்கைகள்</translation>
<translation id="6512448926095770873">இந்தப் பக்கத்தை விட்டு வெளியேறு</translation>
<translation id="6529602333819889595">&amp;நீக்குதலை மீண்டும் செய்</translation>
<translation id="6550675742724504774">விருப்பத்தேர்வுகள்</translation>
-<translation id="6597614308054261376"><ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>ஐப் பார்க்க முயற்சிக்கிறீர்கள். தற்போது இந்தப் பக்கத்தை தரவு சேமிப்பானால் ப்ராக்ஸி செய்ய முடியாது.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> தேடல்</translation>
+<translation id="6597614308054261376"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ஐப் பார்க்க முயற்சிக்கிறீர்கள். தற்போது இந்தப் பக்கத்தை தரவு சேமிப்பானால் ப்ராக்ஸி செய்ய முடியாது.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> தேடல்</translation>
<translation id="6644283850729428850">இந்தக் கொள்கை தவிர்க்கப்பட்டது.</translation>
<translation id="6646897916597483132">கார்டின் முன்புறமுள்ள, 4 இலக்க CVCஐ உள்ளிடவும்</translation>
+<translation id="674375294223700098">தெரியாத சேவையகச் சான்றிதழ் பிழை.</translation>
<translation id="6753269504797312559">கொள்கை மதிப்பு</translation>
<translation id="6831043979455480757">மொழிபெயர்</translation>
<translation id="6839929833149231406">பகுதி</translation>
<translation id="6874604403660855544">&amp;சேர்த்தலை மீண்டும் செய்</translation>
<translation id="6891596781022320156">கொள்கையின் நிலை ஆதரிக்கப்படவில்லை.</translation>
<translation id="6915804003454593391">பயனர்:</translation>
+<translation id="6957887021205513506">சேவையகத்தின் சான்றிதழ் போலியானது போல் தெரிகிறது.</translation>
<translation id="6965382102122355670">சரி</translation>
<translation id="6965978654500191972">சாதனம்</translation>
<translation id="6970216967273061347">மாவட்டம்</translation>
<translation id="6973656660372572881">நிலையான ப்ராக்ஸி சேவையகங்களும் .pac ஸ்கிரிப்ட் URL ஆகிய இரண்டும் குறிப்பிடப்பட்டுள்ளது.</translation>
<translation id="6980028882292583085">Javascript விழிப்பூட்டல்</translation>
<translation id="7012363358306927923">சீனா UnionPay</translation>
+<translation id="7050187094878475250"><ph name="DOMAIN" />ஐ அடைய முயற்சித்துள்ளீர்கள், சேவையகம் வழங்கிய சான்றிதழ் நம்புவதற்கு சாத்தியமற்ற நீண்ட செல்லுபடிக்காலத்தைக் கொண்டுள்ளது.</translation>
<translation id="7087282848513945231">மாகாணம்</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/> க்கான மொழிபெயர்ப்பு தோல்வியடைந்தது.</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" /> க்கான மொழிபெயர்ப்பு தோல்வியடைந்தது.</translation>
<translation id="7139724024395191329">எமிரேட்</translation>
+<translation id="7179921470347911571">இப்போது மீண்டும் தொடங்கு</translation>
<translation id="7180611975245234373">புதுப்பி</translation>
<translation id="7182878459783632708">கொள்கைகள் அமைக்கப்படவில்லை</translation>
-<translation id="7186367841673660872">இந்தப் பக்கமானது<ph name="ORIGINAL_LANGUAGE"/>இலிருந்து<ph name="LANGUAGE_LANGUAGE"/>க்கு மொழிபெயர்க்கப்பட்டது</translation>
+<translation id="7186367841673660872">இந்தப் பக்கமானது<ph name="ORIGINAL_LANGUAGE" />இலிருந்து<ph name="LANGUAGE_LANGUAGE" />க்கு மொழிபெயர்க்கப்பட்டது</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531"><ph name="SITE_NAME"/> தளத்தில் <ph name="SEARCH_TERMS"/> என்பதைத் தேடு</translation>
+<translation id="7208899522964477531"><ph name="SITE_NAME" /> தளத்தில் <ph name="SEARCH_TERMS" /> என்பதைத் தேடு</translation>
+<translation id="725866823122871198">உங்கள் கணினியின் தேதி மற்றும் நேரம் (<ph name="DATE_AND_TIME" />) தவறாக இருப்பதால் <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> க்கான தனிப்பட்ட இணைப்பை ஏற்படுத்த முடியவில்லை.</translation>
<translation id="7275334191706090484">நிர்வகிக்கப்படும் புக்மார்க்குகள்</translation>
<translation id="7298195798382681320">பரிந்துரைத்தவை</translation>
<translation id="7334320624316649418">&amp;மறுவரிசைப்படுத்தலை மீண்டும் செய்</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">கட்டாயம்</translation>
<translation id="7542995811387359312">இந்தப் படிவம் பாதுகாப்பான இணைப்பைப் பயன்படுத்தாத காரணத்தால், தானியங்கு கடன் அட்டை நிரப்புதல் முடக்கப்பட்டிருக்கிறது.</translation>
-<translation id="7568593326407688803">இந்தப் பக்கமானது<ph name="ORIGINAL_LANGUAGE"/>இல் உள்ளது இதை மொழிபெயர்க்க விரும்புகிறீர்களா?</translation>
+<translation id="7567204685887185387">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழில் மோசடி செய்யப்பட்டிருக்கலாம். இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
+<translation id="7568593326407688803">இந்தப் பக்கமானது<ph name="ORIGINAL_LANGUAGE" />இல் உள்ளது இதை மொழிபெயர்க்க விரும்புகிறீர்களா?</translation>
<translation id="7569952961197462199">Chrome இலிருந்து கிரெடிட் கார்டை அகற்றவா?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/> ஐ எப்போதும் மொழிபெயர்க்க வேண்டாம்</translation>
-<translation id="7610193165460212391"><ph name="VALUE"/> என்ற மதிப்பு வரம்பை மீறியுள்ளது.</translation>
+<translation id="7592362899630581445">பெயர் கட்டுப்பாடுகளைச் சேவையகத்தின் சான்றிதழ் மீறுகிறது.</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" /> ஐ எப்போதும் மொழிபெயர்க்க வேண்டாம்</translation>
+<translation id="7610193165460212391"><ph name="VALUE" /> என்ற மதிப்பு வரம்பை மீறியுள்ளது.</translation>
+<translation id="7674629440242451245">புதிய Chrome அம்சங்களில் ஆர்வமாக உள்ளீர்களா? chrome.com/dev இல் எங்களுடைய dev சேனலை முயற்சிக்கவும்.</translation>
<translation id="7752995774971033316">நிர்வகிக்கப்படாதது</translation>
+<translation id="7761701407923456692">சேவையகச் சான்றிதழ் URL உடன் பொருந்தவில்லை.</translation>
<translation id="777702478322588152">ப்ரீஃபெக்சர்</translation>
<translation id="7791543448312431591">சேர்</translation>
<translation id="7805768142964895445">நிலை</translation>
<translation id="7813600968533626083">Chrome இலிருந்து படிவப் பரிந்துரையை அகற்றவா?</translation>
<translation id="7887683347370398519">CVCஐச் சோதித்து, மீண்டும் முயற்சிக்கவும்</translation>
<translation id="7935318582918952113">DOM டிஸ்டில்லர்</translation>
+<translation id="7938958445268990899">சேவையகச் சான்றிதழ் இன்னும் செல்லுபடியாகவில்லை.</translation>
<translation id="7956713633345437162">மொபைல் புக்மார்க்குகள்</translation>
<translation id="7961015016161918242">எப்போதும் இல்லை</translation>
<translation id="7977590112176369853">&lt;வினவலை உள்ளிடுக&gt;</translation>
-<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE"/> ஐ <ph name="TARGET_LANGUAGE"/> க்கு எப்போதும் மொழிபெயர்ப்பு செய்க</translation>
+<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE" /> ஐ <ph name="TARGET_LANGUAGE" /> க்கு எப்போதும் மொழிபெயர்ப்பு செய்க</translation>
<translation id="7988324688042446538">டெஸ்க்டாப் புக்மார்க்குகள்</translation>
<translation id="7995512525968007366">குறிப்பிடப்படவில்லை</translation>
-<translation id="8034522405403831421">இந்தப் பக்கம் <ph name="SOURCE_LANGUAGE"/> மொழியில் உள்ளது. இதை <ph name="TARGET_LANGUAGE"/> க்கு மொழிபெயர்க்கவா?</translation>
+<translation id="8003882219468422867">நிறுவன மேலெழுதுதல்</translation>
+<translation id="8034522405403831421">இந்தப் பக்கம் <ph name="SOURCE_LANGUAGE" /> மொழியில் உள்ளது. இதை <ph name="TARGET_LANGUAGE" /> க்கு மொழிபெயர்க்கவா?</translation>
<translation id="8088680233425245692">கட்டுரையைக் காட்டுவதில் தோல்வி.</translation>
<translation id="8091372947890762290">சேவையகத்தில் செயலாக்கம் நிலுவையிலுள்ளது</translation>
<translation id="8194797478851900357">&amp;நகர்த்தலைச் செயல்தவிர்</translation>
-<translation id="8201077131113104583">&quot;<ph name="EXTENSION_ID"/>&quot; ஐடியுடன் கூடிய நீட்டிப்பிற்கான தவறான புதுப்பிப்பு URL.</translation>
+<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" ஐடியுடன் கூடிய நீட்டிப்பிற்கான தவறான புதுப்பிப்பு URL.</translation>
<translation id="8208216423136871611">சேமிக்காதே</translation>
<translation id="8218327578424803826">ஒதுக்கிய இருப்பிடம்:</translation>
<translation id="8249320324621329438">கடைசியாக எடுத்தது:</translation>
+<translation id="8294431847097064396">மூலம்</translation>
<translation id="8308427013383895095">பிணைய இணைப்பில் ஒரு சிக்கல் இருப்பதால் மொழிப்பெயர்ப்பு தோல்வியடைந்தது.</translation>
<translation id="8311778656528046050">இந்தப் பக்கத்தை நிச்சயமாக மீண்டும் ஏற்றவா?</translation>
<translation id="8349305172487531364">புக்மார்க் பட்டி</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">இதற்குப் பொருந்தும்</translation>
<translation id="8530504477309582336">Google Payments இல் இந்த வகையான கார்டு ஆதரிக்கப்படாது. வேறொரு கார்டைத் தேர்ந்தெடுக்கவும்.</translation>
<translation id="8553075262323480129">பக்கத்தின் மொழியைத் தீர்மானிக்க முடியாததால் மொழிபெயர்ப்பு தோல்வியடைந்தது.</translation>
-<translation id="8571890674111243710"><ph name="LANGUAGE"/> க்கு பக்கத்தை மொழிபெயர்க்கிறது...</translation>
+<translation id="8559762987265718583">உங்கள் சாதனத்தின் தேதி மற்றும் நேரம் (<ph name="DATE_AND_TIME" />) தவறாக உள்ளதால் <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> க்கான தனிப்பட்ட இணைப்பை ஏற்படுத்த முடியவில்லை.</translation>
+<translation id="8571890674111243710"><ph name="LANGUAGE" /> க்கு பக்கத்தை மொழிபெயர்க்கிறது...</translation>
+<translation id="8647750283161643317">எல்லாவற்றையும் இயல்புநிலைக்கு மீட்டமை</translation>
<translation id="8713130696108419660">தொடக்க விசையின் கையொப்பம் தவறானது</translation>
<translation id="8725066075913043281">மீண்டும் முயற்சிக்கவும்</translation>
+<translation id="8738058698779197622">பாதுகாப்பான இணைப்பை அமைக்க, கடிகாரம் சரியாக அமைக்கப்பட வேண்டும். இதற்குக் காரணம், இணையதளங்கள் தங்களைத் தானே அடையாளப்படுத்த பயன்படுத்தும் சான்றிதழ்கள் குறிப்பிட்ட காலநேரத்திற்கே செல்லுபடியாகும். உங்கள் சாதனத்தின் கடிகாரம் தவறாக இருந்தால், Chromium இந்தச் சான்றிதழ்களைச் சரிபார்க்காது.</translation>
<translation id="8790007591277257123">&amp;நீக்குதலை மீண்டும் செய்</translation>
<translation id="8804164990146287819">தனியுரிமைக் கொள்கை</translation>
+<translation id="8820817407110198400">புத்தகக்குறிகள்</translation>
<translation id="8824019021993735287">இப்போது உங்கள் கார்டுகளை Chrome ஆல் சரிபார்க்க முடியவில்லை. பின்னர் முயற்சிக்கவும்.</translation>
<translation id="8834246243508017242">தொடர்புகளைப் பயன்படுத்தி தன்னிரப்பியை இயக்கு…</translation>
<translation id="883848425547221593">மற்ற புக்மார்க்குகள்</translation>
+<translation id="884923133447025588">திரும்பப்பெறுதல் செயல்முறை காணப்படவில்லை.</translation>
<translation id="8866481888320382733">கொள்கை அமைப்புகளை அலசுவதில் பிழை</translation>
<translation id="8876793034577346603">அலசுவதில் பிணைய உள்ளமைவு தோல்வி.</translation>
<translation id="8891727572606052622">தவறான ப்ராக்ஸி முறை.</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/> கட்டளையை இயக்கு: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">மன்னிக்கவும், இந்த சோதனை உங்கள் தளத்தில் கிடைக்கவில்லை.</translation>
+<translation id="8903921497873541725">பெரிதாக்கு</translation>
+<translation id="8932102934695377596">உங்கள் கடிகாரம் மிகவும் பின்தங்கி இருக்கிறது</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" /> கட்டளையை இயக்கு: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">சேவையகச் சான்றிதழ் காலாவதியானது.</translation>
<translation id="8988760548304185580">காலாவதி தேதி மற்றும் கார்டின் பின்புறமுள்ள மூன்று இலக்க CVCஐ உள்ளிடவும்</translation>
-<translation id="9020542370529661692">இந்தப் பக்கம் <ph name="TARGET_LANGUAGE"/> க்கு மொழிபெயர்க்கப்பட்டது</translation>
+<translation id="901974403500617787">கணினி அளவில் பயன்படுத்தப்படும் கொடிகள் பின்வரும் உரிமையாளரால் மட்டுமே அமைக்கப்படும்: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">இந்தப் பக்கம் <ph name="TARGET_LANGUAGE" /> க்கு மொழிபெயர்க்கப்பட்டது</translation>
+<translation id="9049981332609050619">நீங்கள் <ph name="DOMAIN" /> ஐ அடைய முயற்சி செய்தீர்கள், ஆனால் சேவையகம் ஒரு செல்லாத சான்றிதழை வழங்கியது.</translation>
<translation id="9125941078353557812">கார்டின் பின்புறமுள்ள, 3 இலக்க CVCஐ உள்ளிடவும்</translation>
<translation id="9137013805542155359">அசலைக் காண்பி</translation>
<translation id="9148507642005240123">&amp;திருத்தலைச் செயல்தவிர்</translation>
<translation id="9154176715500758432">இந்தப் பக்கத்திலேயே இருக்க</translation>
<translation id="9170848237812810038">&amp;செயல்தவிர்</translation>
+<translation id="917450738466192189">சேவையகச் சான்றிதழ் செல்லுபடியானதல்ல.</translation>
+<translation id="9187827965378254003">ஆ, தற்போது எந்தவொரு சோதனையும் கிடைக்கவில்லை என்பதுபோல தெரிகிறது.</translation>
<translation id="9207861905230894330">கட்டுரையைச் சேர்ப்பதில் தோல்வி.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">படிவத்தை அழி</translation>
+<translation id="988159990683914416">டெவலப்பர் கட்டமைப்பு</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_te.xtb b/chromium/components/strings/components_strings_te.xtb
index 3bb02c1e5e4..50d8acc0dc1 100644
--- a/chromium/components/strings/components_strings_te.xtb
+++ b/chromium/components/strings/components_strings_te.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="te">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="te">
+<translation id="1032854598605920125">సవ్యదిశలో తిప్పు</translation>
<translation id="1055184225775184556">&amp;జోడించడాన్ని రద్దు చేయి</translation>
<translation id="106701514854093668">డెస్క్‌టాప్‌ బుక్‌మార్క్‌లు</translation>
-<translation id="1103523840287552314">ఎల్లప్పుడూ <ph name="LANGUAGE"/>ను అనువదించు</translation>
+<translation id="1080116354587839789">వెడల్పు సరిపోయేలా అమర్చు</translation>
+<translation id="1103523840287552314">ఎల్లప్పుడూ <ph name="LANGUAGE" />ను అనువదించు</translation>
<translation id="1113869188872983271">&amp;మళ్లీ క్రమం చేయడాన్ని రద్దు చేయి</translation>
<translation id="111844081046043029">మీరు దీన్ని ఖచ్చితంగా వదిలేయాలనుకుంటున్నారా?</translation>
<translation id="112840717907525620">విధాన కాష్ సరిపోయింది</translation>
<translation id="1132774398110320017">Chrome స్వయంపూర్తి సెట్టింగ్‌లు...</translation>
-<translation id="1152921474424827756"><ph name="URL"/> యొక్క <ph name="BEGIN_LINK"/>కాష్ చేయబడిన కాపీ<ph name="END_LINK"/>ని ప్రాప్యత చేయండి</translation>
+<translation id="1150979032973867961">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రాన్ని మీ కంప్యూటర్ ఆపరేటింగ్ సిస్టమ్ విశ్వసించలేదు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
+<translation id="1152921474424827756"><ph name="URL" /> యొక్క <ph name="BEGIN_LINK" />కాష్ చేయబడిన కాపీ<ph name="END_LINK" />ని ప్రాప్యత చేయండి</translation>
+<translation id="121201262018556460">మీరు <ph name="DOMAIN" />ను చేరుకోవడానికి ప్రయత్నించారు, కానీ సర్వర్ బలహీన కీని కలిగి ఉన్న ప్రమాణపత్రాన్ని అందించింది. దాడి చేసేవారు ప్రైవేట్ కీని విచ్ఛిన్నం చేశారు మరియు సర్వర్ మీరు ఊహించిన సర్వర్ కాకపోవచ్చు (మీరు దాడి చేసే వారితో కమ్యూనికేట్ చేస్తుండవచ్చు).</translation>
<translation id="1227224963052638717">తెలియని విధానం.</translation>
<translation id="1227633850867390598">విలువను దాచండి</translation>
<translation id="1228893227497259893">ఎంటిటీ ఐడెంటిఫైయర్ చెల్లదు</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">నమోదిత డొమైన్:</translation>
<translation id="1344588688991793829">Chromium స్వయంపూర్తి సెట్టింగ్‌లు...</translation>
<translation id="1426410128494586442">అవును</translation>
+<translation id="1430915738399379752">ముద్రించు</translation>
<translation id="1455235771979731432">మీ కార్డ్‌ను ధృవీకరించడంలో సమస్య ఏర్పడింది. మీ ఇంటర్నెట్ కనెక్షన్ తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి.</translation>
<translation id="1491151370853475546">ఈ పేజీని మళ్లీ లోడ్ చేయి</translation>
<translation id="1549470594296187301">ఈ లక్షణాన్ని ఉపయోగించడానికి జావాస్క్రిప్ట్ తప్పనిసరిగా ప్రారంభించాలి.</translation>
-<translation id="1639239467298939599">లోడ్ అవుతోంది</translation>
<translation id="1640180200866533862">వినియోగదారు విధానాలు</translation>
<translation id="1644184664548287040">నెట్‌వర్క్ కాన్ఫిగరేషన్ చెల్లదు మరియు దిగుమతి చేయడం సాధ్యం కాదు.</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> వద్ద గల పేజీ చెప్పింది:</translation>
+<translation id="1655462015569774233">{1,plural, =1{ఈ సర్వర్ ఇది <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం గడువు నిన్న ముగిసింది. తప్పుగా కాన్ఫిగర్ చేసినందున లేదా దాడిచేసేవారు మీ కనెక్షన్‌కు అంతరాయం కలిగించినందున ఇలా జరిగి ఉండవచ్చు. మీ కంప్యూటర్ గడియారం ప్రస్తుతం <ph name="CURRENT_DATE" />కి సెట్ చేయబడింది. అది సరిగ్గా ఉందా? సరిగ్గా లేకుంటే, మీరు సిస్టమ్ గడియారాన్ని సరిచేసి, ఆపై ఈ పేజీని రీఫ్రెష్ చేయాలి.}other{ఈ సర్వర్ ఇది <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం గడువు # రోజుల క్రితం ముగిసింది. తప్పుగా కాన్ఫిగర్ చేసినందున లేదా దాడిచేసేవారు మీ కనెక్షన్‌కు అంతరాయం కలిగించినందున ఇలా జరిగి ఉండవచ్చు. మీ కంప్యూటర్ గడియారం ప్రస్తుతం <ph name="CURRENT_DATE" />కి సెట్ చేయబడింది. అది సరిగ్గా ఉందా? సరిగ్గా లేకుంటే, మీరు సిస్టమ్ గడియారాన్ని సరిచేసి, ఆపై ఈ పేజీని రీఫ్రెష్ చేయాలి.}}</translation>
+<translation id="168841957122794586">సర్వర్ ప్రమాణపత్రం బలహీన క్రిప్టోగ్రాఫిక్ కీని కలిగి ఉంది.</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> వద్ద గల పేజీ చెప్పింది:</translation>
+<translation id="1706954506755087368">{1,plural, =1{ఈ సర్వర్ ఇది <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం రేపటిది కావచ్చు. తప్పుగా కాన్ఫిగర్ చేసినందున లేదా దాడిచేసేవారు మీ కనెక్షన్‌కు అంతరాయం కలిగించినందున ఇలా జరిగి ఉండవచ్చు.}other{ఈ సర్వర్ ఇది <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం భవిష్యత్తులో # రోజుల తదుపరిది కావచ్చు. తప్పుగా కాన్ఫిగర్ చేసినందున లేదా దాడిచేసేవారు మీ కనెక్షన్‌కు అంతరాయం కలిగించినందున ఇలా జరిగి ఉండవచ్చు.}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రాన్ని మీ పరికర ఆపరేటింగ్ సిస్టమ్ విశ్వసించలేదు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
<translation id="1821930232296380041">చెల్లని అభ్యర్థన లేదా అభ్యర్థన పరామితులు</translation>
-<translation id="1853748787962613237">కథనాన్ని ప్రదర్శించడంలో విఫలమైంది.</translation>
<translation id="1871208020102129563">ప్రాక్సీ స్థిరమైన ప్రాక్సీ సర్వర్‌లను ఉపయోగించడానికి సెట్ చేయబడింది, .pac స్క్రిప్ట్ URLను కాదు.</translation>
-<translation id="1875753206475436906">సమస్య పరిష్కార రకం: <ph name="HEURISTIC_TYPE"/>
- సర్వర్ రకం: <ph name="SERVER_TYPE"/>
- ఫీల్డ్ సంతకం: <ph name="FIELD_SIGNATURE"/>
- ఫారమ్ సంతకం: <ph name="FORM_SIGNATURE"/>
- ప్రయోగం id: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158"><ph name="LINK"/>కి వెళ్లండి</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> బుక్‌మార్క్‌లు</translation>
+<translation id="194030505837763158"><ph name="LINK" />కి వెళ్లండి</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> బుక్‌మార్క్‌లు</translation>
<translation id="1973335181906896915">శ్రేణిగా రూపొందించడంలో లోపం</translation>
+<translation id="1974060860693918893">ఆధునిక</translation>
<translation id="2025186561304664664">ప్రాక్సీ స్వయంచాలకంగా కాన్ఫిగర్ చేయబడేలా సెట్ చేయబడింది.</translation>
<translation id="2025623846716345241">మళ్లీ లోడ్ చేయడాన్ని నిర్ధారించు</translation>
-<translation id="2030481566774242610">మీ ఉద్దేశ్యం <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">మీ ఉద్దేశ్యం <ph name="LINK" />?</translation>
<translation id="2053553514270667976">జిప్ కోడ్</translation>
<translation id="20817612488360358">సిస్టమ్ ప్రాక్సీ సెట్టింగ్‌లు ఉపయోగించడానికి సెట్ చేయబడ్డాయి కానీ స్పష్టమైన ప్రాక్సీ కాన్ఫిగరేషన్ కూడా పేర్కొనబడింది.</translation>
<translation id="2094505752054353250">డొమైన్ సరిపోలలేదు</translation>
<translation id="2096368010154057602">శాఖ</translation>
<translation id="2113977810652731515">కార్డ్</translation>
-<translation id="2114841414352855701">ఇది <ph name="POLICY_NAME"/> ద్వారా భర్తీ చేయబడినందున విస్మరించబడింది.</translation>
+<translation id="2114841414352855701">ఇది <ph name="POLICY_NAME" /> ద్వారా భర్తీ చేయబడినందున విస్మరించబడింది.</translation>
+<translation id="2128531968068887769">దేశీయ క్లయింట్</translation>
<translation id="213826338245044447">మొబైల్ బుక్‌మార్క్‌లు</translation>
+<translation id="2171101176734966184"><ph name="DOMAIN" />ను చేరుకోవడానికి మీరు ప్రయత్నించారు, కానీ సర్వర్ బలహీనమైన సంతకం అల్గారిథమ్‌ను ఉపయోగించి సంతకం చేసిన ప్రమాణపత్రాన్ని అందించింది. అంటే సర్వర్ అందించిన భద్రత ఆధారాలు నకిలీ కావచ్చు మరియు సర్వర్ మీరు ఊహించిన సర్వర్ కాకపోవచ్చు (మీరు దాడి చేసే వారితో కమ్యూనికేట్ చేస్తుండవచ్చు).</translation>
<translation id="2181821976797666341">విధానాలు</translation>
<translation id="2212735316055980242">విధానం కనుగొనబడలేదు</translation>
<translation id="2213606439339815911">నమోదులను పొందుతోంది...</translation>
<translation id="225207911366869382">ఈ విధానం కోసం ఈ విలువ తగ్గించబడింది.</translation>
<translation id="2262243747453050782">HTTP లోపం</translation>
-<translation id="2270192940992995399">కథనాన్ని కనుగొనడంలో విఫలమైంది.</translation>
-<translation id="2328300916057834155"><ph name="ENTRY_INDEX"/>వ సూచికలో చెల్లని బుక్‌మార్క్ విస్మరించబడింది</translation>
+<translation id="2282872951544483773">అందుబాటులో లేని ప్రయోగాలు</translation>
+<translation id="229702904922032456">మూల లేదా మధ్యస్థ ప్రమాణపత్రం గడువు ముగిసింది.</translation>
+<translation id="2328300916057834155"><ph name="ENTRY_INDEX" />వ సూచికలో చెల్లని బుక్‌మార్క్ విస్మరించబడింది</translation>
<translation id="2354001756790975382">ఇతర బుక్‌మార్క్‌లు</translation>
<translation id="2359808026110333948">కొనసాగు</translation>
<translation id="2367567093518048410">స్థాయి</translation>
+<translation id="2384307209577226199">ఎంటర్‌ప్రైజ్ డిఫాల్ట్</translation>
+<translation id="2386255080630008482">సర్వర్ ప్రమాణపత్రం రద్దు చెయ్యబడింది.</translation>
<translation id="2392959068659972793">విలువ సెట్ చేయని విధానాలను చూపు</translation>
<translation id="2396249848217231973">&amp;తొలగించడాన్ని రద్దు చేయి</translation>
+<translation id="2413528052993050574">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం ఉపసంహరించబడి ఉండవచ్చు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
<translation id="2455981314101692989">ఈ వెబ్‌పేజీ ఈ ఫారమ్‌ కోసం స్వయంచాలకంగా పూర్తి చెయ్యడాన్ని ఆపివేసింది.</translation>
<translation id="2479410451996844060">చెల్లని శోధన URL.</translation>
+<translation id="2491120439723279231">సర్వర్ యొక్క ప్రమాణపత్రంలో లోపాలు ఉన్నాయి.</translation>
<translation id="2495083838625180221">JSON పార్సర్</translation>
<translation id="2498091847651709837">కొత్త కార్డ్‌ను స్కాన్ చేయండి</translation>
<translation id="2556876185419854533">&amp;సవరించడాన్ని రద్దు చేయి</translation>
-<translation id="2581221116934462656">మీరు ఈ సైట్‌కు తదుపరిసారి వచ్చినప్పుడు <ph name="LANGUAGE_NAME"/>లో ఉన్న పేజీలకు <ph name="PRODUCT_NAME"/> అనువాదం ఆఫర్ చేయాలని కోరుకుంటున్నారా?</translation>
+<translation id="2581221116934462656">మీరు ఈ సైట్‌కు తదుపరిసారి వచ్చినప్పుడు <ph name="LANGUAGE_NAME" />లో ఉన్న పేజీలకు <ph name="PRODUCT_NAME" /> అనువాదం ఆఫర్ చేయాలని కోరుకుంటున్నారా?</translation>
<translation id="2587841377698384444">డైరెక్టరీ API ID:</translation>
<translation id="2597378329261239068">ఈ పత్రం అనుమతి పదంచే రక్షించబడింది. దయచేసి అనుమతి పదాన్ని నమోదు చేయండి.</translation>
+<translation id="2625385379895617796">మీ గడియారం సమయం భవిష్యత్తులో ఉంది</translation>
<translation id="2639739919103226564">స్థితి: </translation>
+<translation id="2653659639078652383">సమర్పించు</translation>
<translation id="2704283930420550640">విలువ ఆకృతికి సరిపోలలేదు.</translation>
<translation id="2721148159707890343">అభ్యర్థన విజయవంతం అయింది</translation>
+<translation id="2728127805433021124">సర్వర్ యొక్క ప్రమాణపత్రం ఒక బలహీనమైన సంతకం అల్గారిథమ్ ఉపయోగించి సంతకం చేయబడింది.</translation>
<translation id="2774256287122201187">మీరు కొనసాగించవచ్చు. మీరు పేజీకి కొనసాగిస్తే, ఈ హెచ్చరిక ఐదు నిమిషాల పాటు మళ్లీ కనిపించదు.</translation>
<translation id="277499241957683684">పరికరం రికార్డ్ లేదు</translation>
<translation id="2835170189407361413">ఫారమ్‌ను తుడిచివేయి</translation>
-<translation id="2855922900409897335">మీ <ph name="CREDIT_CARD"/>ని ధృవీకరించండి</translation>
+<translation id="2855922900409897335">మీ <ph name="CREDIT_CARD" />ని ధృవీకరించండి</translation>
+<translation id="2915500479781995473">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం గడువు ముగిసింది. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు. మీ కంప్యూటర్ గడియారం ప్రస్తుతం <ph name="CURRENT_TIME" />కి సెట్ చేయబడింది. అది సరిగ్గా ఉందా? లేకపోతే, మీరు మీ సిస్టమ్ గడియారాన్ని సరిచేసి, ఆపై ఈ పేజీని రిఫ్రెష్ చేయండి.</translation>
+<translation id="2922350208395188000">సర్వర్ యొక్క ప్రమాణపత్రం తనిఖీ చెయ్యబడదు.</translation>
+<translation id="2941952326391522266">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం <ph name="DOMAIN2" /> నుండి జారీ చేయబడింది. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
<translation id="2958431318199492670">నెట్‌వర్క్ కాన్ఫిగరేషన్ ONC ప్రమాణానికి అనుకూలంగా లేదు. కాన్ఫిగరేషన్‌లోని భాగాలు దిగుమతి కాకపోయి ఉండకపోవచ్చు.</translation>
<translation id="2972581237482394796">&amp;పునరావృతం</translation>
-<translation id="3010559122411665027">జాబితా నమోదు &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">జాబితా నమోదు "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">చెల్లని విధాన రకం</translation>
<translation id="3105172416063519923">అసెట్ ID:</translation>
<translation id="3145945101586104090">ప్రతిస్పందనను డీకోడ్ చేయడంలో విఫలమైంది</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">కనుగొను</translation>
<translation id="3174168572213147020">దీవి</translation>
<translation id="3219579145727097045">మీ కార్డ్ గడువు ముగింపు తేదీ మరియు దాని వెనుకవైపు ఉండే 4 అంకెల CVCని నమోదు చేయండి</translation>
-<translation id="3228969707346345236">పేజీ ఇప్పటికే <ph name="LANGUAGE"/>లో ఉన్నందున అనువాదం విఫలమైంది.</translation>
+<translation id="3225919329040284222">అంతర్నిర్మిత అంచనాలకు సరిపోలని ఒక ధృవీకరణ పత్రాన్ని సర్వర్ సమర్పించింది. మిమ్మల్ని సంరక్షించే దిశగా నిర్దిష్ట, ఉన్నత స్ధాయి భద్రతా వెబ్‌సైట్‌ల కోసం ఈ అంచనాలు చేర్చబడ్డాయి.</translation>
+<translation id="3228969707346345236">పేజీ ఇప్పటికే <ph name="LANGUAGE" />లో ఉన్నందున అనువాదం విఫలమైంది.</translation>
<translation id="3270847123878663523">&amp;మళ్లీ క్రమం చేయడాన్ని రద్దు చేయి</translation>
+<translation id="3286538390144397061">ఇప్పుడు పునఃప్రారంభించండి</translation>
<translation id="333371639341676808">అదనపు డైలాగ్‌లను సృష్టించకుండా ఈ పేజీని అడ్డుకో</translation>
-<translation id="3369366829301677151">మీ <ph name="CREDIT_CARD"/>ని నవీకరించి, ధృవీకరించండి</translation>
+<translation id="3340978935015468852">సెట్టింగ్‌లు</translation>
+<translation id="3369192424181595722">గడియారం లోపం</translation>
+<translation id="3369366829301677151">మీ <ph name="CREDIT_CARD" />ని నవీకరించి, ధృవీకరించండి</translation>
<translation id="337363190475750230">కేటాయింపు తీసివేయబడింది</translation>
<translation id="3377188786107721145">విధాన అన్వయ లోపం</translation>
<translation id="3380365263193509176">తెలియని లోపం</translation>
<translation id="3380864720620200369">క్లయింట్ ID:</translation>
<translation id="3427342743765426898">&amp;సవరించడాన్ని పునరావృతం చేయి</translation>
+<translation id="3435896845095436175">ప్రారంభించండి</translation>
<translation id="3450660100078934250">మాస్టర్‌కార్డ్</translation>
<translation id="3452404311384756672">విరామాన్ని పొందండి:</translation>
+<translation id="3462200631372590220">అధునాతనం దాచు</translation>
+<translation id="3528171143076753409">సర్వర్ యొక్క ప్రమాణ పత్రం నమ్మదగినది కాదు.</translation>
<translation id="3542684924769048008">దీని కోసం పాస్‌వర్డ్‌ను ఉపయోగించండి:</translation>
<translation id="3583757800736429874">&amp;తరలించడాన్ని పునరావృతం చేయి</translation>
<translation id="3623476034248543066">విలువను చూపండి</translation>
+<translation id="3648607100222897006">ఈ ప్రయోగాత్మక లక్షణాలు ఏ సమయంలోనైనా మారవచ్చు, విభజించబడవచ్చు లేదా అదృశ్యం కావచ్చు. మీరు ఈ ప్రయోగాలలో ఒకదాన్ని ఆన్‌ చేస్తే జరిగే దానికి మేము ఖచ్చితంగా హామీలు ఇవ్వలేము మరియు మీ బ్రౌజర్ ఆకస్మికంగా మూసుకునిపోవచ్చు. హాస్యాన్ని ప్రక్కన పెడితే, మీ బ్రౌజర్ మీ మొత్తం డేటా తొలగించవచ్చు లేదా అనుకోని విధంగా మీ భద్రతా మరియు గోప్యత రాజీపడవచ్చు. మీరు ప్రారంభించిన ఏవేని ప్రయోగాలు ఈ బ్రౌజర్ యొక్క వినియోగదారులందరికి ప్రారంభించబడతాయి. దయచేసి జాగ్రత్తగా కొనసాగండి.</translation>
<translation id="3650584904733503804">ప్రామాణీకరణ విజయవంతం అయింది</translation>
<translation id="370665806235115550">లోడ్ అవుతోంది...</translation>
<translation id="3712624925041724820">లైసెన్స్‌లు అయిపోయాయి</translation>
<translation id="3739623965217189342">మీరు కాపీ చేసిన లింక్</translation>
<translation id="375403751935624634">సర్వర్ లోపం వల్ల అనువాదం విఫలమైంది.</translation>
<translation id="385051799172605136">వెనుకకు</translation>
+<translation id="3858027520442213535">తేదీ మరియు సమయాన్ని నవీకరించు</translation>
<translation id="3884278016824448484">వైరుధ్యమైన పరికరం ఐడెంటిఫైయర్</translation>
<translation id="3885155851504623709">పారిష్</translation>
<translation id="3934680773876859118">PDF పత్రాన్ని లోడ్ చెయ్యడానికి విఫలమైంది</translation>
<translation id="3963721102035795474">పాఠకుని మోడ్</translation>
<translation id="4030383055268325496">&amp;జోడించడాన్ని రద్దు చేయి</translation>
-<translation id="4058922952496707368">కీ &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">హెచ్చరిక</translation>
+<translation id="4058922952496707368">కీ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">ప్రాక్సీ కాన్ఫిగరేషన్ స్థిరమైన ప్రాక్సీ సర్వర్‌లను కాకుండా, ఒక .pac స్క్రిప్ట్ URLను ఉపయోగించడానికి సెట్ చేయబడింది.</translation>
<translation id="409504436206021213">మళ్లీ లోడ్ చేయవద్దు</translation>
<translation id="4103249731201008433">పరికరం క్రమ సంఖ్య చెల్లదు</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">చెల్లని సంతకం</translation>
<translation id="4269787794583293679">(వినియోగదారు పేరు లేదు)</translation>
<translation id="4300246636397505754">తల్లి/తండ్రి సూచనలు</translation>
-<translation id="4372948949327679948">ఆశిస్తున్న <ph name="VALUE_TYPE"/> విలువ.</translation>
+<translation id="4325863107915753736">కథనాన్ని కనుగొనడం విఫలమైంది</translation>
+<translation id="4372948949327679948">ఆశిస్తున్న <ph name="VALUE_TYPE" /> విలువ.</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" />ను చేరుకోవడానికి మీరు ప్రయత్నించారు, కానీ సర్వర్ అందించిన ప్రమాణపత్రాన్ని దాన్ని జారీ చేసినవారు రద్దు చేసారు. సర్వర్ అందించిన భద్రత ఆధారాలు ఖచ్చితంగా విశ్వసించబడలేదని దీని అర్థం. మీరు దాడి చేసే వారితో కమ్యూనికేట్ చేస్తూ ఉండవచ్చు.</translation>
+<translation id="4394049700291259645">ఆపివెయ్యి</translation>
+<translation id="4424024547088906515">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రాన్ని Chrome విశ్వసించలేదు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
<translation id="443673843213245140">ప్రాక్సీని ఉపయోగించడం ఆపివేయబడింది కానీ స్పష్టమైన ప్రాక్సీ కాన్ఫిగరేషన్ పేర్కొనబడింది.</translation>
-<translation id="4506176782989081258">ధృవీకరణ లోపం: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">ధృవీకరణ లోపం: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Chrome నుండి చిరునామాను తీసివేయాలా?</translation>
<translation id="4594403342090139922">&amp;తొలగించడాన్ని రద్దు చేయి</translation>
<translation id="4607653538520819196">ఈ పేజీ డేటా సేవర్ ద్వారా ప్రాక్సీ చేయబడదు.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రంలో లోపాలు ఉన్నాయి. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
<translation id="4726672564094551039">విధానాలను మళ్లీ లోడ్ చేయి</translation>
+<translation id="4728558894243024398">ప్లాట్‌ఫారమ్</translation>
+<translation id="4771973620359291008">తెలియని లోపం ఒకటి ఏర్పడింది.</translation>
<translation id="4800132727771399293">మీ గడువు ముగింపు తేదీ మరియు CVCని తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి</translation>
<translation id="4813512666221746211">నెట్‌వర్క్ లోపం</translation>
+<translation id="4816492930507672669">పేజీకి తగినట్లు అమర్చు</translation>
<translation id="4850886885716139402">వీక్షణ</translation>
-<translation id="4923417429809017348">ఈ పేజీ తెలియని భాష నుండి <ph name="LANGUAGE_LANGUAGE"/>కు అనువదించబడింది</translation>
+<translation id="4923417429809017348">ఈ పేజీ తెలియని భాష నుండి <ph name="LANGUAGE_LANGUAGE" />కు అనువదించబడింది</translation>
<translation id="4926049483395192435">ఖచ్చితంగా పేర్కొనాలి.</translation>
<translation id="4968547170521245791">ప్రాక్సీ చేయలేనివి</translation>
-<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE"/> నుండి <ph name="TARGET_LANGUAGE"/>కి అనువదించాలా?</translation>
+<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE" /> నుండి <ph name="TARGET_LANGUAGE" />కి అనువదించాలా?</translation>
<translation id="5019198164206649151">బ్యాకింగ్ నిల్వ చెల్లని స్థితిలో ఉంది</translation>
<translation id="5031870354684148875">Google అనువాదం గురించి</translation>
+<translation id="5045550434625856497">తప్పు పాస్‌వర్డ్</translation>
+<translation id="5087286274860437796">ప్రస్తుతం సర్వర్ ప్రమాణపత్రం చెల్లదు.</translation>
<translation id="5089810972385038852">రాష్ట్రం</translation>
+<translation id="5094747076828555589">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రాన్ని Chromium విశ్వసించలేదు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
<translation id="5095208057601539847">ప్రావిన్స్</translation>
<translation id="5145883236150621069">విధాన ప్రతిస్పందనలో లోపం కోడ్ ఉంది</translation>
<translation id="5172758083709347301">మెషీన్</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/>లో లేదా? ఈ లోపాన్ని నివేదించండి</translation>
+<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" />లో లేదా? ఈ లోపాన్ని నివేదించండి</translation>
<translation id="5190835502935405962">బుక్‌మార్క్‌ల బార్</translation>
+<translation id="5199729219167945352">ప్రయోగాలు</translation>
+<translation id="5251803541071282808">క్లౌడ్</translation>
<translation id="5295309862264981122">నావిగేషన్‌ను నిర్థారించండి</translation>
<translation id="5299298092464848405">విధానాన్ని అన్వయించడంలో లోపం</translation>
+<translation id="5316812925700871227">అపసవ్య దిశలో తిప్పు</translation>
<translation id="5317780077021120954">సేవ్ చేయి</translation>
<translation id="536296301121032821">విధాన సెట్టింగ్‌లను నిల్వ చేయడంలో విఫలమైంది</translation>
-<translation id="5439770059721715174">&quot;<ph name="ERROR_PATH"/>&quot;లో స్కీమా ప్రామాణీకరణ లోపం: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం ప్రస్తుతం చెల్లదు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడి చేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
+<translation id="5439770059721715174">"<ph name="ERROR_PATH" />"లో స్కీమా ప్రామాణీకరణ లోపం: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">చెల్లని విధాన సమయముద్ర</translation>
<translation id="5470861586879999274">&amp;సవరించడాన్ని పునరావృతం చేయి</translation>
<translation id="5509780412636533143">నిర్వహించబడిన బుక్‌మార్క్‌లు</translation>
<translation id="5523118979700054094">విధానం పేరు</translation>
<translation id="552553974213252141">వచనం సరిగ్గా సంగ్రహించబడిందా?</translation>
<translation id="5540224163453853">అభ్యర్థించిన కథనాన్ని కనుగొనడం సాధ్యపడలేదు.</translation>
+<translation id="5556459405103347317">రీలోడ్</translation>
<translation id="5565735124758917034">సక్రియం</translation>
<translation id="560412284261940334">నిర్వహణకు మద్దతు లేదు</translation>
<translation id="5629630648637658800">విధాన సెట్టింగ్‌లను లోడ్ చేయడంలో విఫలమైంది</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">ప్రస్తుత వినియోగదారు</translation>
<translation id="5813119285467412249">&amp;జోడించడాన్ని పునరావృతం చేయి</translation>
<translation id="5872918882028971132">తల్లి/తండ్రి సూచనలు</translation>
-<translation id="587701087903783706">మొబైల్-అనుకూలం వీక్షణను మూసివేయి</translation>
<translation id="59107663811261420">ఈ వ్యాపారి కోసం Google Payments ఈ రకమైన కార్డ్‌కి మద్దతివ్వదు. దయచేసి వేరొక కార్డ్‌ను ఎంచుకోండి.</translation>
+<translation id="5975083100439434680">దూరంగా జూమ్ చెయ్యి</translation>
<translation id="5989320800837274978">స్థిర ప్రాక్సీ సర్వర్‌లు లేదా ఒక .pac స్క్రిప్ట్ URL పేర్కొనబడలేదు.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">మూసివేయి</translation>
+<translation id="6060685159320643512">జాగ్రత్త, ఈ ప్రయోగాలు విఫలం కావచ్చు</translation>
+<translation id="6151417162996330722">సర్వర్ ప్రమాణపత్రం చెల్లుబాటు వ్యవధి చాలా ఎక్కువ కాలం ఉంది.</translation>
<translation id="6154808779448689242">అందించబడిన విధాన టోకెన్ ప్రస్తుత టోకెన్‌కు సరిపోలలేదు</translation>
<translation id="6165508094623778733">మరింత తెలుసుకోండి</translation>
<translation id="6259156558325130047">&amp;మళ్లీ క్రమం చేయడాన్ని పునరావృతం చేయి</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> బుక్‌మార్క్‌లు</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> బుక్‌మార్క్‌లు</translation>
<translation id="6282194474023008486">పోస్టల్ కోడ్</translation>
<translation id="6337534724793800597">పేరు ద్వారా విధానాలను ఫిల్టర్ చేయి</translation>
+<translation id="6387478394221739770">అద్భుతమైన క్రొత్త Chrome లక్షణాల పట్ల ఆసక్తిగా ఉన్నారా? chrome.com/betaలో మా బీటా ఛానెల్‌ను ప్రయత్నించండి.</translation>
+<translation id="6426993025560594914">మీ ప్లాట్‌ఫారమ్‌లో అన్ని ప్రయోగాలు అందుబాటులో ఉన్నాయి!</translation>
<translation id="6445051938772793705">దేశం</translation>
<translation id="6458467102616083041">విధానంచే డిపాల్ట్ శోధన ఆపివేయబడినందున విస్మరించబడింది.</translation>
<translation id="647261751007945333">పరికర విధానాలు</translation>
<translation id="6512448926095770873">ఈ పేజీని వదిలివేయండి</translation>
<translation id="6529602333819889595">&amp;తొలగించడాన్ని పునరావృతం చేయి</translation>
<translation id="6550675742724504774">ఎంపికలు</translation>
-<translation id="6597614308054261376">మీరు <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>ని సందర్శించడానికి ప్రయత్నిస్తున్నారు. ప్రస్తుతం ఈ పేజీ డేటా సేవర్ ద్వారా ప్రాక్సీ చేయబడదు.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> శోధన</translation>
+<translation id="6597614308054261376">మీరు <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ని సందర్శించడానికి ప్రయత్నిస్తున్నారు. ప్రస్తుతం ఈ పేజీ డేటా సేవర్ ద్వారా ప్రాక్సీ చేయబడదు.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> శోధన</translation>
<translation id="6644283850729428850">ఈ విధానం విలువ తగ్గించబడింది.</translation>
<translation id="6646897916597483132">మీ కార్డ్ ముందువైపు ఉండే 4 అంకెల CVCని నమోదు చేయండి</translation>
+<translation id="674375294223700098">తెలియని సర్వర్ ప్రమాణపత్రం లోపం.</translation>
<translation id="6753269504797312559">విధానం విలువ</translation>
<translation id="6831043979455480757">అనువదించు</translation>
<translation id="6839929833149231406">ప్రాంతం</translation>
<translation id="6874604403660855544">&amp;జోడించడాన్ని పునరావృతం చేయి</translation>
<translation id="6891596781022320156">విధానం స్థాయికి మద్దతు లేదు.</translation>
<translation id="6915804003454593391">వినియోగదారు:</translation>
+<translation id="6957887021205513506">సర్వర్ ధృవీకరణ పత్రం చెల్లదు.</translation>
<translation id="6965382102122355670">సరే</translation>
<translation id="6965978654500191972">పరికరం</translation>
<translation id="6970216967273061347">జిల్లా</translation>
<translation id="6973656660372572881">రెండు స్థిర ప్రాక్సీ సర్వర్లు మరియు ఒక .pac స్క్రిప్ట్ URL పేర్కొనబడ్డాయి.</translation>
<translation id="6980028882292583085">Javascript హెచ్చరిక</translation>
<translation id="7012363358306927923">చైనా యూనియన్ పే</translation>
+<translation id="7050187094878475250">మీరు <ph name="DOMAIN" />ని చేరుకోవడానికి ప్రయత్నించారు, కానీ సర్వర్ అందించిన ప్రమాణపత్రం విశ్వసించలేనంత ఎక్కువ చెల్లుబాటు వ్యవధిని కలిగి ఉంది.</translation>
<translation id="7087282848513945231">కౌంటి</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/>కు అనువాదం విఫలమైంది.</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" />కు అనువాదం విఫలమైంది.</translation>
<translation id="7139724024395191329">ఎమిరేట్</translation>
+<translation id="7179921470347911571">ఇప్పుడే పునఃప్రారంభించు</translation>
<translation id="7180611975245234373">రీఫ్రెష్ చేయి</translation>
<translation id="7182878459783632708">విధానాలను సెట్ చేయలేదు</translation>
-<translation id="7186367841673660872">ఈ పేజీ<ph name="ORIGINAL_LANGUAGE"/>నుండి<ph name="LANGUAGE_LANGUAGE"/>కు అనువదించబడింది</translation>
+<translation id="7186367841673660872">ఈ పేజీ<ph name="ORIGINAL_LANGUAGE" />నుండి<ph name="LANGUAGE_LANGUAGE" />కు అనువదించబడింది</translation>
<translation id="719464814642662924">వీసా</translation>
-<translation id="7208899522964477531"><ph name="SITE_NAME"/> కోసం <ph name="SEARCH_TERMS"/> శోధించండి</translation>
+<translation id="7208899522964477531"><ph name="SITE_NAME" /> కోసం <ph name="SEARCH_TERMS" /> శోధించండి</translation>
+<translation id="725866823122871198">మీ కంప్యూటర్ తేదీ మరియు సమయం (<ph name="DATE_AND_TIME" />) తప్పుగా ఉన్నందున <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />కి ప్రైవేట్ కనెక్షన్ ఏర్పాటు చేయబడదు.</translation>
<translation id="7275334191706090484">నిర్వహించబడిన బుక్‌మార్క్‌లు</translation>
<translation id="7298195798382681320">సిఫార్సు చేయబడినవి</translation>
<translation id="7334320624316649418">&amp;మళ్లీ క్రమం చేయడాన్ని పునరావృతం చేయి</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">తప్పనిసరి</translation>
<translation id="7542995811387359312">ఈ ఫారమ్ సురక్షిత కనెక్షన్‌ని ఉపయోగించనందున స్వయంచాలకంగా క్రెడిట్ కార్డ్ పూర్తి చెయ్యడం ఆపివేయబడింది.</translation>
-<translation id="7568593326407688803">ఈ పేజీ<ph name="ORIGINAL_LANGUAGE"/>లో ఉంది మీరు దీన్ని అనువదించాలనుకుంటున్నారా?</translation>
+<translation id="7567204685887185387">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం మోసపూరితంగా జారీ అయ్యి ఉండవచ్చు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
+<translation id="7568593326407688803">ఈ పేజీ<ph name="ORIGINAL_LANGUAGE" />లో ఉంది మీరు దీన్ని అనువదించాలనుకుంటున్నారా?</translation>
<translation id="7569952961197462199">Chrome నుండి క్రెడిట్ కార్డ్‌ను తీసివేయాలా?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/>ను ఎప్పటికీ అనువదించవద్దు</translation>
-<translation id="7610193165460212391">విలువ <ph name="VALUE"/> పరిధి వెలుపల ఉంది.</translation>
+<translation id="7592362899630581445">సర్వర్ యొక్క ప్రమాణపత్రం పేరు పరిమితులను ఉల్లంఘిస్తోంది.</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" />ను ఎప్పటికీ అనువదించవద్దు</translation>
+<translation id="7610193165460212391">విలువ <ph name="VALUE" /> పరిధి వెలుపల ఉంది.</translation>
+<translation id="7674629440242451245">అద్భుతమైన క్రొత్త Chrome లక్షణాల పట్ల ఆసక్తిగా ఉన్నారా? chrome.com/devలో మా డెవలపర్ ఛానెల్‌ను ప్రయత్నించండి.</translation>
<translation id="7752995774971033316">నిర్వహించడం లేదు</translation>
+<translation id="7761701407923456692">URLతో సర్వర్ ప్రమాణపత్రం సరిపోలడం లేదు.</translation>
<translation id="777702478322588152">అధికారిక నివాసం</translation>
<translation id="7791543448312431591">జోడించు</translation>
<translation id="7805768142964895445">స్థితి</translation>
<translation id="7813600968533626083">Chrome నుండి ఫారమ్ సూచనను తీసివేయాలా?</translation>
<translation id="7887683347370398519">మీ CVCని తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి</translation>
<translation id="7935318582918952113">DOM డిస్టిల్లర్</translation>
+<translation id="7938958445268990899">సర్వర్ ప్రమాణపత్రం ఇంకా చెల్లుబాటు కాదు.</translation>
<translation id="7956713633345437162">మొబైల్ బుక్‌మార్క్‌లు</translation>
<translation id="7961015016161918242">ఎప్పుడూ లేదు</translation>
<translation id="7977590112176369853">&lt;ప్రశ్నను ఎంటర్ చెయ్యండి&gt;</translation>
-<translation id="7983301409776629893">ఎల్లప్పుడూ <ph name="ORIGINAL_LANGUAGE"/>ను <ph name="TARGET_LANGUAGE"/>కు అనువదించు</translation>
+<translation id="7983301409776629893">ఎల్లప్పుడూ <ph name="ORIGINAL_LANGUAGE" />ను <ph name="TARGET_LANGUAGE" />కు అనువదించు</translation>
<translation id="7988324688042446538">డెస్క్‌టాప్ బుక్‌మార్క్‌లు</translation>
<translation id="7995512525968007366">పేర్కొనబడలేదు</translation>
-<translation id="8034522405403831421">ఈ పేజీ <ph name="SOURCE_LANGUAGE"/>లో ఉంది. దీన్ని <ph name="TARGET_LANGUAGE"/>లోకి అనువదించాలా?</translation>
+<translation id="8003882219468422867">ఎంటర్‌ప్రైజ్ భర్తీ</translation>
+<translation id="8034522405403831421">ఈ పేజీ <ph name="SOURCE_LANGUAGE" />లో ఉంది. దీన్ని <ph name="TARGET_LANGUAGE" />లోకి అనువదించాలా?</translation>
<translation id="8088680233425245692">కథనాన్ని వీక్షించడంలో విఫలమైంది.</translation>
<translation id="8091372947890762290">సక్రియం సర్వర్‌లో పెండింగ్‌లో ఉంది</translation>
<translation id="8194797478851900357">&amp;తరలించడాన్ని రద్దు చేయి</translation>
-<translation id="8201077131113104583">ID &quot;<ph name="EXTENSION_ID"/>&quot; ఉన్న పొడిగింపు కోసం నవీకరణ URL చెల్లదు.</translation>
+<translation id="8201077131113104583">ID "<ph name="EXTENSION_ID" />" ఉన్న పొడిగింపు కోసం నవీకరణ URL చెల్లదు.</translation>
<translation id="8208216423136871611">సేవ్ చేయవద్దు</translation>
<translation id="8218327578424803826">కేటాయించిన స్థానం:</translation>
<translation id="8249320324621329438">చివరగా పొందబడినవి:</translation>
+<translation id="8294431847097064396">మూలం</translation>
<translation id="8308427013383895095">నెట్‌వర్క్ కనెక్షన్‌తో సమస్య ఉన్నందున అనువాదం విఫలమైంది.</translation>
<translation id="8311778656528046050">మీరు ఈ పేజీని మళ్లీ లోడ్ చేయాలనుకుంటున్నారా?</translation>
<translation id="8349305172487531364">బుక్‌మార్క్‌ల పట్టీ</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">వీటికి వర్తిస్తుంది</translation>
<translation id="8530504477309582336">Google Payments ఈ రకమైన కార్డ్‌కి మద్దతివ్వదు. దయచేసి వేరొక కార్డ్‌ను ఎంచుకోండి.</translation>
<translation id="8553075262323480129">పేజీ భాష నిర్థారించలేకపోయినందున అనువాదం విఫలమైంది.</translation>
-<translation id="8571890674111243710">పేజీని <ph name="LANGUAGE"/>కు అనువదిస్తోంది...</translation>
+<translation id="8559762987265718583">మీ పరికరం తేదీ మరియు సమయం (<ph name="DATE_AND_TIME" />) తప్పుగా ఉన్నందున <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />కి ప్రైవేట్ కనెక్షన్ ఏర్పాటు చేయబడదు.</translation>
+<translation id="8571890674111243710">పేజీని <ph name="LANGUAGE" />కు అనువదిస్తోంది...</translation>
+<translation id="8647750283161643317">అన్నింటినీ డిఫాల్ట్‌కు రీసెట్ చేయి</translation>
<translation id="8713130696108419660">చెల్లని ప్రారంభ సంతకం</translation>
<translation id="8725066075913043281">మళ్ళీ ప్రయత్నించండి</translation>
+<translation id="8738058698779197622">సురక్షిత కనెక్షన్‌ను ఏర్పాటు చేయడానికి, మీ గడియారాన్ని సరైన సమయానికి సెట్ చేయాలి. ఎందుకంటే వెబ్‌సైట్‌లు వాటిని గుర్తించడానికి ఉపయోగించే ప్రమాణపత్రాలు నిర్దిష్ట కాలవ్యవధుల్లో మాత్రమే చెల్లుబాటు అవుతాయి. మీ పరికరం యొక్క గడియారం సమయం తప్పుగా ఉన్నందున, Chromium ఈ ప్రమాణపత్రాలను ధృవీకరించడానికి వీలుపడలేదు.</translation>
<translation id="8790007591277257123">&amp;తొలగించడాన్ని పునరావృతం చేయి</translation>
<translation id="8804164990146287819">గోప్యతా విధానం</translation>
+<translation id="8820817407110198400">బుక్‌మార్క్‌లు</translation>
<translation id="8824019021993735287">Chrome ప్రస్తుతం మీ కార్డ్‌ను ధృవీకరించలేకపోయింది. దయచేసి తర్వాత మళ్లీ ప్రయత్నించండి.</translation>
<translation id="8834246243508017242">పరిచయాలను ఉపయోగించి స్వీయపూర్తిని ప్రారంభించండి…</translation>
<translation id="883848425547221593">ఇతర బుక్‌మార్క్‌లు:</translation>
+<translation id="884923133447025588">ఏ రద్దు విధానం కనుగొనబడలేదు.</translation>
<translation id="8866481888320382733">విధాన సెట్టింగ్‌లను అన్వయించడంలో లోపం</translation>
<translation id="8876793034577346603">నెట్‌వర్క్ కాన్ఫిగరేషన్ అన్వయించబడటంలో విఫలమైంది.</translation>
<translation id="8891727572606052622">చెల్లని ప్రాక్సీ మోడ్.</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/> ఆదేశాన్ని అమలు చెయ్యి: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">క్షమించండి, ఈ ప్రయోగం మీ ప్లాట్‌ఫారమ్‌లో అందుబాటులో లేదు.</translation>
+<translation id="8903921497873541725">దగ్గరికి జూమ్ చెయ్యి</translation>
+<translation id="8932102934695377596">మీ గడియారం సమయం గతంలో ఉంది</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" /> ఆదేశాన్ని అమలు చెయ్యి: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">సర్వర్ యొక్క ప్రమాణపత్రం గడువు ముగిసింది.</translation>
<translation id="8988760548304185580">మీ కార్డ్ గడువు ముగింపు తేదీ మరియు దాని వెనుకవైపు ఉండే 3 అంకెల CVCని నమోదు చేయండి</translation>
-<translation id="9020542370529661692">ఈ పేజీ <ph name="TARGET_LANGUAGE"/>కి అనువదించబడింది</translation>
+<translation id="901974403500617787">సిస్టమ్ వ్యాప్తంగా వర్తింపజేయబడే ఫ్లాగ్‌లు యజమాని ద్వారా మాత్రమే సెట్ చేయబడతాయి: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">ఈ పేజీ <ph name="TARGET_LANGUAGE" />కి అనువదించబడింది</translation>
+<translation id="9049981332609050619">మీరు <ph name="DOMAIN" />ని చేరుకోవడానికి ప్రయత్నించారు, కానీ సర్వర్ ఒక చెల్లుబాటులో లేని ప్రమాణపత్రంని అందించింది.</translation>
<translation id="9125941078353557812">మీ కార్డ్ వెనుకవైపు ఉండే 3 అంకెల CVCని నమోదు చేయండి</translation>
<translation id="9137013805542155359">అసలును చూపించు</translation>
<translation id="9148507642005240123">&amp;సవరించడాన్ని రద్దు చేయి</translation>
<translation id="9154176715500758432">ఈ పేజీపై ఉండు</translation>
<translation id="9170848237812810038">&amp;అన్డు</translation>
+<translation id="917450738466192189">సర్వర్ యొక్క ప్రమాణపత్రం చెల్లుబాటు కాదు.</translation>
+<translation id="9187827965378254003">అయ్యో, ప్రస్తుతానికి ఎటువంటి ప్రయోగాలు అందుబాటులో లేనట్లు ఉంది.</translation>
<translation id="9207861905230894330">కథనాన్ని జోడించడంలో విఫలమైంది.</translation>
<translation id="933712198907837967">డైనర్స్ క్లబ్</translation>
+<translation id="935608979562296692">ఫారమ్‌ను తీసివేయండి</translation>
+<translation id="988159990683914416">డెవలపర్ బిల్డ్</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_th.xtb b/chromium/components/strings/components_strings_th.xtb
index c940d7f0398..8988d2e8a21 100644
--- a/chromium/components/strings/components_strings_th.xtb
+++ b/chromium/components/strings/components_strings_th.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="th">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="th">
+<translation id="1032854598605920125">หมุนตามเข็มนาฬิกา</translation>
<translation id="1055184225775184556">&amp;เลิกทำการเพิ่ม</translation>
<translation id="106701514854093668">บุ๊กมาร์กบนเดสก์ท็อป</translation>
-<translation id="1103523840287552314">แปลภาษา<ph name="LANGUAGE"/>ทุกครั้ง</translation>
+<translation id="1080116354587839789">พอดีกับความกว้าง</translation>
+<translation id="1103523840287552314">แปลภาษา<ph name="LANGUAGE" />ทุกครั้ง</translation>
<translation id="1113869188872983271">&amp;เลิกทำการจัดลำดับใหม่</translation>
<translation id="111844081046043029">คุณแน่ใจหรือไม่ว่าต้องการออกจากหน้านี้</translation>
<translation id="112840717907525620">แคชนโยบายใช้ได้</translation>
<translation id="1132774398110320017">การตั้งค่าป้อนข้อความอัตโนมัติของ Chrome...</translation>
-<translation id="1152921474424827756">เข้าถึง<ph name="BEGIN_LINK"/>สำเนาแคช<ph name="END_LINK"/>ของ <ph name="URL"/></translation>
+<translation id="1150979032973867961">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะระบบปฏิบัติการของคอมพิวเตอร์ของคุณไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
+<translation id="1152921474424827756">เข้าถึง<ph name="BEGIN_LINK" />สำเนาแคช<ph name="END_LINK" />ของ <ph name="URL" /></translation>
+<translation id="121201262018556460">คุณพยายามเข้าถึง <ph name="DOMAIN" /> แต่เซิร์ฟเวอร์แสดงใบรับรองที่มีคีย์ที่ไม่รัดกุม ผู้โจมตีอาจทำให้คีย์ส่วนตัวเสียหายไปแล้วและเซิร์ฟเวอร์นี้อาจไม่ใช่เซิร์ฟเวอร์ที่คุณคิด (คุณอาจกำลังติดต่อกับผู้โจมตี)</translation>
<translation id="1227224963052638717">นโยบายที่ไม่รู้จัก</translation>
<translation id="1227633850867390598">ซ่อนค่า</translation>
<translation id="1228893227497259893">ตัวระบุเอนทิตีไม่ถูกต้อง</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">โดเมนการลงทะเบียน:</translation>
<translation id="1344588688991793829">การตั้งค่าป้อนข้อความอัตโนมัติของ Chromium...</translation>
<translation id="1426410128494586442">ใช่</translation>
+<translation id="1430915738399379752">พิมพ์</translation>
<translation id="1455235771979731432">เกิดปัญหาในการยืนยันบัตรของคุณ โปรดตรวจสอบการเชื่อมต่ออินเทอร์เน็ตและลองอีกครั้ง</translation>
<translation id="1491151370853475546">โหลดหน้าเว็บนี้ซ้ำ</translation>
<translation id="1549470594296187301">ต้องเปิดใช้ JavaScript เพื่อใช้คุณลักษณะนี้</translation>
-<translation id="1639239467298939599">กำลังโหลด</translation>
<translation id="1640180200866533862">นโยบายผู้ใช้</translation>
<translation id="1644184664548287040">การกำหนดค่าเครือข่ายไม่ถูกต้องและไม่สามารถนำเข้า</translation>
-<translation id="1693754753824026215">หน้าเว็บที่ <ph name="SITE"/> แจ้งว่า:</translation>
+<translation id="1655462015569774233">{1,plural, =1{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยหมดอายุไปเมื่อวานนี้ โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ ขณะนี้นาฬิกาของคุณตั้งค่าไว้ที่วันที่ <ph name="CURRENT_DATE" /> การตั้งค่านี้ถูกต้องไหม หากไม่ถูกต้อง คุณควรแก้ไขนาฬิกาของระบบและรีเฟรชหน้านี้}other{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยหมดอายุไปเมื่อ # วันที่ผ่านมา โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ ขณะนี้นาฬิกาของคุณตั้งค่าไว้ที่วันที่ <ph name="CURRENT_DATE" /> การตั้งค่านี้ถูกต้องไหม หากไม่ถูกต้อง คุณควรแก้ไขนาฬิกาของระบบและรีเฟรชหน้านี้}}</translation>
+<translation id="168841957122794586">ใบรับรองของเซิร์ฟเวอร์มีคีย์การเข้ารหัสที่ไม่รัดกุม</translation>
+<translation id="1693754753824026215">หน้าเว็บที่ <ph name="SITE" /> แจ้งว่า:</translation>
+<translation id="1706954506755087368">{1,plural, =1{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยควรจะเริ่มใช้งานได้ตั้งแต่วันพรุ่งนี้ โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ}other{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยควรจะเริ่มใช้งานได้ในอีก # วันข้างหน้า โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะระบบปฏิบัติการของอุปกรณ์ของคุณไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
<translation id="1821930232296380041">คำขอหรือพารามิเตอร์คำขอไม่ถูกต้อง</translation>
-<translation id="1853748787962613237">การแสดงบทความล้มเหลว</translation>
<translation id="1871208020102129563">พร็อกซีถูกตั้งค่าให้ใช้พร็อกซีเซิร์ฟเวอร์แบบคงที่ ไม่ใช่ URL สคริปต์ .pac</translation>
-<translation id="1875753206475436906">ประเภทการเรียนรู้: <ph name="HEURISTIC_TYPE"/>
- ประเภทเซิร์ฟเวอร์: <ph name="SERVER_TYPE"/>
- ช่องลายเซ็น: <ph name="FIELD_SIGNATURE"/>
- ฟอร์มลายเซ็น: <ph name="FORM_SIGNATURE"/>
- รหัสการทดลอง: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">ไปที่ <ph name="LINK"/></translation>
-<translation id="1962204205936693436">บุ๊กมาร์กของ <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">ไปที่ <ph name="LINK" /></translation>
+<translation id="1962204205936693436">บุ๊กมาร์กของ <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">ข้อผิดพลาดในการจัดเรียง</translation>
+<translation id="1974060860693918893">ขั้นสูง</translation>
<translation id="2025186561304664664">พร็อกซีถูกตั้งค่าให้ทำการกำหนดค่าโดยอัตโนมัติ</translation>
<translation id="2025623846716345241">ยืนยันการโหลดซ้ำ</translation>
-<translation id="2030481566774242610">หรือคุณหมายถึง <ph name="LINK"/></translation>
+<translation id="2030481566774242610">หรือคุณหมายถึง <ph name="LINK" /></translation>
<translation id="2053553514270667976">รหัสไปรษณีย์</translation>
<translation id="20817612488360358">มีการกำหนดให้ใช้การตั้งค่าพร็อกซีระบบ แต่ก็มีการระบุการกำหนดค่าพร็อกซีอย่างชัดเจนไว้ด้วยเช่นกัน</translation>
<translation id="2094505752054353250">โดเมนไม่ตรง</translation>
<translation id="2096368010154057602">จังหวัด</translation>
<translation id="2113977810652731515">บัตร</translation>
-<translation id="2114841414352855701">ไม่สนใจเพราะถูกแทนที่โดย <ph name="POLICY_NAME"/></translation>
+<translation id="2114841414352855701">ไม่สนใจเพราะถูกแทนที่โดย <ph name="POLICY_NAME" /></translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">บุ๊กมาร์กบนมือถือ</translation>
+<translation id="2171101176734966184">คุณพยายามเข้าถึง <ph name="DOMAIN" /> แต่เซิร์ฟเวอร์แสดงใบรับรองที่เซ็นชื่อด้วยอัลกอริทึมลายเซ็นที่ไม่รัดกุม ซึ่งหมายความว่าข้อมูลรับรองด้านความปลอดภัยที่เซิร์ฟเวอร์แสดงอาจถูกปลอมแปลงขึ้น และเซิร์ฟเวอร์ดังกล่าวอาจไม่ใช่เซิร์ฟเวอร์ที่คุณคิด (คุณอาจกำลังติดต่อกับผู้โจมตี)</translation>
<translation id="2181821976797666341">นโยบาย</translation>
<translation id="2212735316055980242">ไม่พบนโยบาย</translation>
<translation id="2213606439339815911">กำลังดึงรายการ...</translation>
<translation id="225207911366869382">เลิกใช้งานค่านี้กับนโยบายนี้</translation>
<translation id="2262243747453050782">ข้อผิดพลาดของ HTTP</translation>
-<translation id="2270192940992995399">การค้นหาบทความล้มเหลว</translation>
-<translation id="2328300916057834155">บุ๊กมาร์กที่ไม่ถูกต้องถูกเพิกเฉยที่ดัชนี <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">การทดลองที่ไม่พร้อมใช้งาน</translation>
+<translation id="229702904922032456">ใบรับรองที่ออกเองหรือใบรับรองโดยคนกลางหมดอายุแล้ว</translation>
+<translation id="2328300916057834155">บุ๊กมาร์กที่ไม่ถูกต้องถูกเพิกเฉยที่ดัชนี <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">บุ๊กมาร์กอื่นๆ</translation>
<translation id="2359808026110333948">ดำเนินการต่อ</translation>
<translation id="2367567093518048410">ระดับ</translation>
+<translation id="2384307209577226199">ค่าเริ่มต้นขององค์กร</translation>
+<translation id="2386255080630008482">ใบรับรองของเซิร์ฟเวอร์ถูกเพิกถอนแล้ว</translation>
<translation id="2392959068659972793">แสดงนโยบายโดยที่ไม่ได้ตั้งค่า</translation>
<translation id="2396249848217231973">&amp;เลิกทำการนำออก</translation>
+<translation id="2413528052993050574">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะอาจมีการเพิกถอนใบรับรองความปลอดภัย โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
<translation id="2455981314101692989">หน้าเว็บนี้ปิดใช้งานการป้อนอัตโนมัติสำหรับฟอร์มนี้</translation>
<translation id="2479410451996844060">URL ค้นหาไม่ถูกต้อง</translation>
+<translation id="2491120439723279231">ใบรับรองของเซิร์ฟเวอร์มีข้อผิดพลาด</translation>
<translation id="2495083838625180221">โปรแกรมแยกวิเคราะห์ JSON</translation>
<translation id="2498091847651709837">สแกนบัตรใหม่</translation>
<translation id="2556876185419854533">&amp;เลิกทำการแก้ไข</translation>
-<translation id="2581221116934462656">คุณต้องการให้ <ph name="PRODUCT_NAME"/> เสนอที่จะแปลหน้าในภาษา<ph name="LANGUAGE_NAME"/>จากไซต์นี้ในครั้งถัดไปไหม</translation>
+<translation id="2581221116934462656">คุณต้องการให้ <ph name="PRODUCT_NAME" /> เสนอที่จะแปลหน้าในภาษา<ph name="LANGUAGE_NAME" />จากไซต์นี้ในครั้งถัดไปไหม</translation>
<translation id="2587841377698384444">รหัส API ไดเรกทอรี:</translation>
<translation id="2597378329261239068">เอกสารนี้ได้รับการป้องกันด้วยรหัสผ่าน โปรดป้อนรหัสผ่าน</translation>
+<translation id="2625385379895617796">นาฬิกาเร็วเกินไป</translation>
<translation id="2639739919103226564">สถานะ:</translation>
+<translation id="2653659639078652383">ส่ง</translation>
<translation id="2704283930420550640">ค่าไม่ตรงกับรูปแบบ</translation>
<translation id="2721148159707890343">คำขอสำเร็จ</translation>
+<translation id="2728127805433021124">ใบรับรองของเซิร์ฟเวอร์ถูกเซ็นชื่อด้วยอัลกอริทึมลายเซ็นที่ไม่รัดกุม</translation>
<translation id="2774256287122201187">คุณสามารถดำเนินการต่อได้ หากคุณไปยังหน้าดังกล่าว คำเตือนนี้จะไม่ปรากฏอีกเป็นเวลา 5 นาที</translation>
<translation id="277499241957683684">ไม่มีอุปกรณ์บันทึก</translation>
<translation id="2835170189407361413">ล้างฟอร์ม</translation>
-<translation id="2855922900409897335">ยืนยัน <ph name="CREDIT_CARD"/> ของคุณ</translation>
+<translation id="2855922900409897335">ยืนยัน <ph name="CREDIT_CARD" /> ของคุณ</translation>
+<translation id="2915500479781995473">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เนื่องจากใบรับรองความปลอดภัยได้หมดอายุแล้ว โดยอาจมีสาเหตุมาจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อ ขณะนี้นาฬิกาในคอมพิวเตอร์ของคุณตั้งเวลาไว้ที่ <ph name="CURRENT_TIME" /> หากไม่ถูกต้อง โปรดตั้งนาฬิกาของระบบให้ถูกต้อง แล้วรีเฟรชหน้านี้อีกครั้ง</translation>
+<translation id="2922350208395188000">ไม่สามารถตรวจสอบใบรับรองของเซิร์ฟเวอร์</translation>
+<translation id="2941952326391522266">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยมาจาก <ph name="DOMAIN2" /> โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
<translation id="2958431318199492670">การกำหนดค่าเครือข่ายไม่เป็นไปตามมาตรฐาน ONC การกำหนดค่าบางส่วนอาจไม่ได้รับการนำเข้า</translation>
<translation id="2972581237482394796">&amp;ทำซ้ำ</translation>
-<translation id="3010559122411665027">รายการที่เข้ามา &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">รายการที่เข้ามา "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">ประเภทนโยบายไม่ถูกต้อง</translation>
<translation id="3105172416063519923">รหัสสินทรัพย์:</translation>
<translation id="3145945101586104090">การถอดรหัสการตอบกลับล้มเหลว</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">เกาะ</translation>
<translation id="3219579145727097045">ป้อนวันหมดอายุและ CVC 4 หลักจากด้านหน้าบัตร</translation>
-<translation id="3228969707346345236">การแปลล้มเหลวเนื่องจากหน้าเว็บนี้เป็นภาษา<ph name="LANGUAGE"/>อยู่แล้ว</translation>
+<translation id="3225919329040284222">เซิร์ฟเวอร์แสดงใบรับรองที่ไม่ตรงกับการคาดการณ์ที่มีอยู่ การคาดการณ์เหล่านี้มีอยู่ในบางเว็บไซต์ที่มีการรักษาความปลอดภัยสูงเพื่อปกป้องคุณ</translation>
+<translation id="3228969707346345236">การแปลล้มเหลวเนื่องจากหน้าเว็บนี้เป็นภาษา<ph name="LANGUAGE" />อยู่แล้ว</translation>
<translation id="3270847123878663523">&amp;เลิกทำการจัดลำดับใหม่</translation>
+<translation id="3286538390144397061">รีสตาร์ทเดี๋ยวนี้</translation>
<translation id="333371639341676808">ป้องกันหน้านี้จากการสร้างการโต้ตอบเพิ่มเติม</translation>
-<translation id="3369366829301677151">อัปเดตและยืนยัน <ph name="CREDIT_CARD"/> ของคุณ</translation>
+<translation id="3340978935015468852">การตั้งค่า</translation>
+<translation id="3369192424181595722">ข้อผิดพลาดของนาฬิกา</translation>
+<translation id="3369366829301677151">อัปเดตและยืนยัน <ph name="CREDIT_CARD" /> ของคุณ</translation>
<translation id="337363190475750230">ยกเลิกการจัดเตรียมแล้ว</translation>
<translation id="3377188786107721145">ข้อผิดพลาดในการแยกวิเคราะห์นโยบาย</translation>
<translation id="3380365263193509176">ข้อผิดพลาดที่ไม่รู้จัก</translation>
<translation id="3380864720620200369">รหัสลูกค้า:</translation>
<translation id="3427342743765426898">&amp;ทำซ้ำการแก้ไข</translation>
+<translation id="3435896845095436175">เปิดการใช้งาน</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">ช่วงการดึงข้อมูล:</translation>
+<translation id="3462200631372590220">ซ่อนข้อมูลขั้นสูง</translation>
+<translation id="3528171143076753409">ใบรับรองของเซิร์ฟเวอร์ไม่น่าเชื่อถือ</translation>
<translation id="3542684924769048008">ใช้รหัสผ่านสำหรับ:</translation>
<translation id="3583757800736429874">&amp;ทำซ้ำการย้าย</translation>
<translation id="3623476034248543066">แสดงค่า</translation>
+<translation id="3648607100222897006">คุณลักษณะทดลองเหล่านี้อาจมีการเปลี่ยนแปลง เสียหาย หรือยกเลิกไปได้ตลอดเวลา เราไม่รับประกันใดๆ เกี่ยวกับสิ่งที่อาจเกิดขึ้นทั้งสิ้นหากคุณเปิดใช้การทดลองรายการใดรายการหนึ่งนี้ เบราว์เซอร์ของคุณอาจพังโดยไม่มีสัญญาณเตือน ยิ่งไปกว่านั้น เบราว์เซอร์อาจลบข้อมูลทั้งหมดของคุณได้ หรือการรักษาความปลอดภัยและความเป็นส่วนตัวของคุณอาจโดนคุกคามโดยไม่คาดคิด การทดลองใดๆ ที่คุณเปิดใช้งานจะเปิดใช้สำหรับผู้ใช้ทุกคนที่ใช้เบราว์เซอร์นี้ด้วย โปรดดำเนินการด้วยความระมัดระวัง</translation>
<translation id="3650584904733503804">การตรวจสอบสำเร็จ</translation>
<translation id="370665806235115550">กำลังโหลด...</translation>
<translation id="3712624925041724820">ใบอนุญาตหมด</translation>
<translation id="3739623965217189342">ลิงก์ที่คุณคัดลอกมา</translation>
<translation id="375403751935624634">การแปลล้มเหลวเนื่องจากข้อผิดพลาดของเซิร์ฟเวอร์</translation>
<translation id="385051799172605136">กลับ</translation>
+<translation id="3858027520442213535">อัปเดตวันที่และเวลา</translation>
<translation id="3884278016824448484">ตัวชี้อุปกรณ์ขัดแย้งกัน</translation>
<translation id="3885155851504623709">เมือง</translation>
<translation id="3934680773876859118">โหลดเอกสาร PDF ล้มเหลว</translation>
<translation id="3963721102035795474">โหมดนักอ่าน</translation>
<translation id="4030383055268325496">&amp;เลิกทำการเพิ่ม</translation>
-<translation id="4058922952496707368">คีย์ &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">คำเตือน</translation>
+<translation id="4058922952496707368">คีย์ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">การกำหนดค่าพร็อกซีมีการตั้งค่าให้ใช้ URL สคริปต์ .pac ไม่ใช่พร็อกซีเซิร์ฟเวอร์แบบคงที่</translation>
<translation id="409504436206021213">อย่าโหลดซ้ำ</translation>
<translation id="4103249731201008433">หมายเลขซีเรียลของอุปกรณ์ไม่ถูกต้อง</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">ลายเซ็นไม่เหมาะสม</translation>
<translation id="4269787794583293679">(ไม่มีชื่อผู้ใช้)</translation>
<translation id="4300246636397505754">คำแนะนำระดับบนสุด</translation>
-<translation id="4372948949327679948">ค่า <ph name="VALUE_TYPE"/> ที่คาดไว้</translation>
+<translation id="4325863107915753736">การค้นหาบทความล้มเหลว</translation>
+<translation id="4372948949327679948">ค่า <ph name="VALUE_TYPE" /> ที่คาดไว้</translation>
+<translation id="4377125064752653719">คุณพยายามเข้าถึง <ph name="DOMAIN" /> แต่ใบรับรองที่เซิร์ฟเวอร์แจ้งมาถูกเพิกถอนโดยผู้ออกใบรับรอง ซึ่งหมายความว่าข้อมูลรับรองด้านความปลอดภัยที่เซิร์ฟเวอร์แจ้งมานั้นไม่สามารถเชื่อถือได้ คุณอาจกำลังติดต่อกับคนที่คิดจะโจมตีคุณ</translation>
+<translation id="4394049700291259645">ปิดการใช้งาน</translation>
+<translation id="4424024547088906515">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะ Chrome ไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
<translation id="443673843213245140">การใช้พร็อกซีถูกปิดใช้งาน แต่มีการระบุการกำหนดค่าพร็อกซีอย่างชัดเจน</translation>
-<translation id="4506176782989081258">ข้อผิดพลาดในการตรวจสอบ: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">ข้อผิดพลาดในการตรวจสอบ: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">นำที่อยู่ออกจาก Chrome ไหม</translation>
<translation id="4594403342090139922">&amp;เลิกทำการนำออก</translation>
<translation id="4607653538520819196">โปรแกรมประหยัดอินเทอร์เน็ตไม่สามารถพร็อกซีหน้านี้ได้</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยมีข้อผิดพลาด โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
<translation id="4726672564094551039">โหลดนโยบายซ้ำ</translation>
+<translation id="4728558894243024398">แพลตฟอร์ม</translation>
+<translation id="4771973620359291008">มีข้อผิดพลาดที่ไม่ทราบเกิดขึ้น</translation>
<translation id="4800132727771399293">ตรวจสอบวันหมดอายุและ CVC แล้วลองอีกครั้ง</translation>
<translation id="4813512666221746211">ข้อผิดพลาดของเครือข่าย</translation>
+<translation id="4816492930507672669">พอดีกับหน้า</translation>
<translation id="4850886885716139402">มุมมอง</translation>
-<translation id="4923417429809017348">หน้านี้แปลจากภาษาที่ไม่รู้จักเป็นภาษา <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">หน้านี้แปลจากภาษาที่ไม่รู้จักเป็นภาษา <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">ต้องระบุ</translation>
<translation id="4968547170521245791">ไม่สามารถพร็อกซีได้</translation>
-<translation id="498957508165411911">แปลจาก <ph name="ORIGINAL_LANGUAGE"/> เป็น <ph name="TARGET_LANGUAGE"/> หรือไม่</translation>
+<translation id="498957508165411911">แปลจาก <ph name="ORIGINAL_LANGUAGE" /> เป็น <ph name="TARGET_LANGUAGE" /> หรือไม่</translation>
<translation id="5019198164206649151">ไม่สามารถจัดเก็บเนื่องจากระบบแบ็คเอนด์อยู่ในสถานะไม่ดี</translation>
<translation id="5031870354684148875">เกี่ยวกับ Google แปลภาษา</translation>
+<translation id="5045550434625856497">รหัสผ่านไม่ถูกต้อง</translation>
+<translation id="5087286274860437796">ใบรับรองของเซิร์ฟเวอร์ไม่สามารถใช้ได้ในขณะนี้</translation>
<translation id="5089810972385038852">รัฐ</translation>
+<translation id="5094747076828555589">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะ Chromium ไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
<translation id="5095208057601539847">จังหวัด</translation>
<translation id="5145883236150621069">มีรหัสข้อผิดพลาดในการตอบกลับนโยบาย</translation>
<translation id="5172758083709347301">ผู้ใช้คอมพิวเตอร์นี้</translation>
-<translation id="5179510805599951267">หากไม่มีในภาษา <ph name="ORIGINAL_LANGUAGE"/> ให้รายงานข้อผิดพลาดนี้</translation>
+<translation id="5179510805599951267">หากไม่มีในภาษา <ph name="ORIGINAL_LANGUAGE" /> ให้รายงานข้อผิดพลาดนี้</translation>
<translation id="5190835502935405962">แถบบุ๊กมาร์ก</translation>
+<translation id="5199729219167945352">การทดลอง</translation>
+<translation id="5251803541071282808">ระบบคลาวด์</translation>
<translation id="5295309862264981122">ยืนยันการนำทาง</translation>
<translation id="5299298092464848405">ข้อผิดพลาดในการแยกวิเคราะห์นโยบาย</translation>
+<translation id="5316812925700871227">หมุนทวนเข็มนาฬิกา</translation>
<translation id="5317780077021120954">บันทึก</translation>
<translation id="536296301121032821">ไม่สามารถจัดเก็บการตั้งค่านโยบาย</translation>
-<translation id="5439770059721715174">ข้อผิดพลาดในการตรวจสอบรูปแบบที่ &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เนื่องจากใบรับรองความปลอดภัยไม่สามารถใช้ได้ในขณะนี้ ซึ่งอาจเป็นเพราะการกำหนดค่าที่ไม่ถูกต้องหรือมีผู้โจมตีที่ขัดขวางการเชื่อมต่อของคุณ</translation>
+<translation id="5439770059721715174">ข้อผิดพลาดในการตรวจสอบรูปแบบที่ "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">เวลาบันทึกของนโยบายไม่เหมาะสม</translation>
<translation id="5470861586879999274">&amp;ทำซ้ำการแก้ไข</translation>
<translation id="5509780412636533143">บุ๊กมาร์กที่มีการจัดการ</translation>
<translation id="5523118979700054094">ชื่อนโยบาย</translation>
<translation id="552553974213252141">ดึงข้อความออกมาถูกต้องไหม</translation>
<translation id="5540224163453853">ไม่พบบทความที่ขอ</translation>
+<translation id="5556459405103347317">โหลดใหม่</translation>
<translation id="5565735124758917034">ใช้งานอยู่</translation>
<translation id="560412284261940334">ไม่สนับสนุนการจัดการ</translation>
<translation id="5629630648637658800">ไม่สามารถโหลดการตั้งค่านโยบาย</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">ผู้ใช้ปัจจุบัน</translation>
<translation id="5813119285467412249">&amp;ทำซ้ำการเพิ่ม</translation>
<translation id="5872918882028971132">คำแนะนำระดับบนสุด</translation>
-<translation id="587701087903783706">ปิดมุมมองที่เหมาะกับอุปกรณ์เคลื่อนที่</translation>
<translation id="59107663811261420">Google Payments ไม่สนับสนุนบัตรประเภทนี้สำหรับผู้ขายรายนี้ โปรดเลือกบัตรอื่น</translation>
+<translation id="5975083100439434680">ย่อ</translation>
<translation id="5989320800837274978">ไม่มีการระบุทั้งพร็อกซีเซิร์ฟเวอร์แบบคงที่หรือ URL สคริปต์ .pac</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">ปิด</translation>
+<translation id="6060685159320643512">ระวัง การทดลองนี้อาจเป็นอันตราย</translation>
+<translation id="6151417162996330722">ใบรับรองเซิร์ฟเวอร์มีระยะเวลาที่สามารถใช้ได้นานเกินไป</translation>
<translation id="6154808779448689242">โทเค็นนโยบายที่ส่งกลับไม่ตรงกับโทเค็นปัจจุบัน</translation>
<translation id="6165508094623778733">เรียนรู้เพิ่มเติม</translation>
<translation id="6259156558325130047">&amp;ทำซ้ำการจัดลำดับใหม่</translation>
-<translation id="6263376278284652872">บุ๊กมาร์ก <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">บุ๊กมาร์ก <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">รหัสไปรษณีย์</translation>
<translation id="6337534724793800597">กรองนโยบายตามชื่อ</translation>
+<translation id="6387478394221739770">หากสนใจในคุณลักษณะสุดเจ๋งของ Chrome ใหม่ ลองใช้เวอร์ชันเบต้าของเราที่ chrome.com/beta</translation>
+<translation id="6426993025560594914">การทดลองทั้งหมดพร้อมใช้งานบนแพลตฟอร์มของคุณ!</translation>
<translation id="6445051938772793705">ประเทศ</translation>
<translation id="6458467102616083041">ไม่ใช้งานเนื่องจากการค้นหาเริ่มต้นถูกปิดใช้งานตามนโยบาย</translation>
<translation id="647261751007945333">นโยบายอุปกรณ์</translation>
<translation id="6512448926095770873">ออกจากหน้านี้</translation>
<translation id="6529602333819889595">&amp;ทำซ้ำการนำออก</translation>
<translation id="6550675742724504774">ตัวเลือก</translation>
-<translation id="6597614308054261376">คุณกำลังพยายามเข้าถึง <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> โปรแกรมประหยัดอินเทอร์เน็ตไม่สามารถพร็อกซีหน้านี้ได้ในเวลานี้</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> ค้นหา</translation>
+<translation id="6597614308054261376">คุณกำลังพยายามเข้าถึง <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> โปรแกรมประหยัดอินเทอร์เน็ตไม่สามารถพร็อกซีหน้านี้ได้ในเวลานี้</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> ค้นหา</translation>
<translation id="6644283850729428850">นโยบายนี้ถูกยกเลิกแล้ว</translation>
<translation id="6646897916597483132">ป้อน CVC 4 หลักจากด้านหน้าบัตร</translation>
+<translation id="674375294223700098">ข้อผิดพลาดใบรับรองของเซิร์ฟเวอร์ที่ไม่รู้จัก</translation>
<translation id="6753269504797312559">ค่านโยบาย</translation>
<translation id="6831043979455480757">แปลภาษา</translation>
<translation id="6839929833149231406">พื้นที่</translation>
<translation id="6874604403660855544">&amp;ทำซ้ำการเพิ่ม</translation>
<translation id="6891596781022320156">ระดับนโยบายไม่ได้รับการสนับสนุน</translation>
<translation id="6915804003454593391">ผู้ใช้:</translation>
+<translation id="6957887021205513506">ใบรับรองของเซิร์ฟเวอร์น่าจะเป็นของปลอม</translation>
<translation id="6965382102122355670">ตกลง</translation>
<translation id="6965978654500191972">อุปกรณ์</translation>
<translation id="6970216967273061347">เขต</translation>
<translation id="6973656660372572881">มีการระบุทั้งพร็อกซีเซิร์ฟเวอร์แบบคงที่และ URL สคริปต์ .pac ไว้</translation>
<translation id="6980028882292583085">แจ้งเตือน JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">คุณพยายามเข้าถึง <ph name="DOMAIN" /> แต่เซิร์ฟเวอร์ได้แสดงใบรับรองที่มีระยะเวลาที่สามารถใช้ได้นานเกินกว่าที่จะเชื่อถือได้</translation>
<translation id="7087282848513945231">อำเภอ</translation>
-<translation id="7108649287766967076">การแปลเป็น <ph name="TARGET_LANGUAGE"/> ล้มเหลว</translation>
+<translation id="7108649287766967076">การแปลเป็น <ph name="TARGET_LANGUAGE" /> ล้มเหลว</translation>
<translation id="7139724024395191329">เอมิเรต</translation>
+<translation id="7179921470347911571">เปิดใช้งานใหม่เดี๋ยวนี้</translation>
<translation id="7180611975245234373">รีเฟรช</translation>
<translation id="7182878459783632708">ไม่ได้กำหนดนโยบายไว้</translation>
-<translation id="7186367841673660872">แปลหน้าเว็บนี้จาก<ph name="ORIGINAL_LANGUAGE"/>เป็น<ph name="LANGUAGE_LANGUAGE"/>แล้ว</translation>
+<translation id="7186367841673660872">แปลหน้าเว็บนี้จาก<ph name="ORIGINAL_LANGUAGE" />เป็น<ph name="LANGUAGE_LANGUAGE" />แล้ว</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">ค้นหาข้อความ <ph name="SEARCH_TERMS"/> จาก <ph name="SITE_NAME"/></translation>
+<translation id="7208899522964477531">ค้นหาข้อความ <ph name="SEARCH_TERMS" /> จาก <ph name="SITE_NAME" /></translation>
+<translation id="725866823122871198">ไม่สามารถเริ่มการเชื่อมต่อส่วนตัวกับ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ได้เนื่องจากวันที่และเวลาของคอมพิวเตอร์ (<ph name="DATE_AND_TIME" />) ไม่ถูกต้อง</translation>
<translation id="7275334191706090484">บุ๊กมาร์กที่มีการจัดการ</translation>
<translation id="7298195798382681320">แนะนำ</translation>
<translation id="7334320624316649418">&amp;ทำซ้ำการจัดลำดับใหม่</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">จำเป็น</translation>
<translation id="7542995811387359312">การป้อนหมายเลขบัตรเครดิตอัตโนมัติถูกปิดใช้งานเนื่องจากฟอร์มนี้ไม่ได้ใช้การเชื่อมต่อที่ปลอดภัย</translation>
-<translation id="7568593326407688803">หน้าเว็บนี้เป็น<ph name="ORIGINAL_LANGUAGE"/>คุณต้องการแปลหรือไม่</translation>
+<translation id="7567204685887185387">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะอาจมีการออกใบรับรองความปลอดภัยปลอม โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
+<translation id="7568593326407688803">หน้าเว็บนี้เป็น<ph name="ORIGINAL_LANGUAGE" />คุณต้องการแปลหรือไม่</translation>
<translation id="7569952961197462199">นำบัตรเครดิตออกจาก Chrome ไหม</translation>
-<translation id="7600965453749440009">ไม่ต้องแปลภาษา<ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">ค่าอยู่นอกช่วง <ph name="VALUE"/></translation>
+<translation id="7592362899630581445">ใบรับรองของเซิร์ฟเวอร์ละเมิดข้อกำหนดชื่อ</translation>
+<translation id="7600965453749440009">ไม่ต้องแปลภาษา<ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">ค่าอยู่นอกช่วง <ph name="VALUE" /></translation>
+<translation id="7674629440242451245">หากสนใจในคุณลักษณะใหม่ๆ สุดเจ๋งของ Chrome ลองใช้เวอร์ชันที่กำลังพัฒนาของเราที่ chrome.com/dev</translation>
<translation id="7752995774971033316">ไม่ได้จัดการ</translation>
+<translation id="7761701407923456692">ใบรับรองของเซิร์ฟเวอร์ไม่ตรงกับ URL</translation>
<translation id="777702478322588152">เขตปกครอง</translation>
<translation id="7791543448312431591">เพิ่ม</translation>
<translation id="7805768142964895445">สถานะ</translation>
<translation id="7813600968533626083">นำคำแนะนำสำหรับแบบฟอร์มออกจาก Chrome ไหม</translation>
<translation id="7887683347370398519">ตรวจสอบ CVC และลองอีกครั้ง</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">ใบรับรองของเซิร์ฟเวอร์ยังไม่ถูกต้อง</translation>
<translation id="7956713633345437162">บุ๊กมาร์กบนมือถือ</translation>
<translation id="7961015016161918242">ไม่เคย</translation>
<translation id="7977590112176369853">&lt;ป้อนคำค้นหา&gt;</translation>
-<translation id="7983301409776629893">แปล <ph name="ORIGINAL_LANGUAGE"/> เป็น <ph name="TARGET_LANGUAGE"/> เสมอ</translation>
+<translation id="7983301409776629893">แปล <ph name="ORIGINAL_LANGUAGE" /> เป็น <ph name="TARGET_LANGUAGE" /> เสมอ</translation>
<translation id="7988324688042446538">บุ๊กมาร์กบนเดสก์ท็อป</translation>
<translation id="7995512525968007366">ไม่ได้ระบุ</translation>
-<translation id="8034522405403831421">หน้าเว็บนี้อยู่ในภาษา<ph name="SOURCE_LANGUAGE"/> ต้องการแปลเป็นภาษา<ph name="TARGET_LANGUAGE"/>ไหม</translation>
+<translation id="8003882219468422867">การลบล้างขององค์กร</translation>
+<translation id="8034522405403831421">หน้าเว็บนี้อยู่ในภาษา<ph name="SOURCE_LANGUAGE" /> ต้องการแปลเป็นภาษา<ph name="TARGET_LANGUAGE" />ไหม</translation>
<translation id="8088680233425245692">การดูบทความล้มเหลว</translation>
<translation id="8091372947890762290">กำลังรอการเปิดใช้งานบนเซิร์ฟเวอร์</translation>
<translation id="8194797478851900357">&amp;เลิกทำการย้าย</translation>
-<translation id="8201077131113104583">การอัปเดต URL ไม่ถูกต้องสำหรับส่วนขยายรหัส &quot;<ph name="EXTENSION_ID"/>&quot;</translation>
+<translation id="8201077131113104583">การอัปเดต URL ไม่ถูกต้องสำหรับส่วนขยายรหัส "<ph name="EXTENSION_ID" />"</translation>
<translation id="8208216423136871611">ไม่บันทึก</translation>
<translation id="8218327578424803826">ตำแหน่งที่มอบหมาย:</translation>
<translation id="8249320324621329438">เรียกดูครั้งสุดท้ายเมื่อ:</translation>
+<translation id="8294431847097064396">แหล่งที่มา</translation>
<translation id="8308427013383895095">การแปลล้มเหลวเนื่องจากเกิดปัญหาการเชื่อมต่อกับเครือข่าย </translation>
<translation id="8311778656528046050">คุณแน่ใจหรือไม่ว่าต้องการโหลดหน้าเว็บนี้ซ้ำ</translation>
<translation id="8349305172487531364">แถบบุ๊กมาร์ก</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">ใช้กับ</translation>
<translation id="8530504477309582336">Google Payments ไม่สนับสนุนบัตรประเภทนี้ โปรดเลือกบัตรอื่น</translation>
<translation id="8553075262323480129">การแปลล้มเหลวเนื่องจากไม่สามารถระบุภาษาของหน้าเว็บนี้ได้</translation>
-<translation id="8571890674111243710">กำลังแปลหน้าเว็บนี้เป็นภาษา<ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">ไม่สามารถเริ่มการเชื่อมต่อส่วนตัวกับ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ได้เนื่องจากวันที่และเวลาของอุปกรณ์ (<ph name="DATE_AND_TIME" />) ไม่ถูกต้อง</translation>
+<translation id="8571890674111243710">กำลังแปลหน้าเว็บนี้เป็นภาษา<ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">รีเซ็ตทั้งหมดเป็นค่าเริ่มต้น</translation>
<translation id="8713130696108419660">ลายเซ็นแรกเริ่มไม่ถูกต้อง</translation>
<translation id="8725066075913043281">ลองอีกครั้ง</translation>
+<translation id="8738058698779197622">หากต้องเริ่มการเชื่อมต่อที่ปลอดภัย นาฬิกาจะต้องตั้งค่าไว้อย่างถูกต้อง เนื่องจากใบรับรองที่เว็บไซต์ใช้เพื่อระบุตนเองจะใช้ได้เฉพาะช่วงเวลาหนึ่งเท่านั้น นาฬิกาของอุปกรณ์ไม่ถูกต้อง Chromium จึงไม่สามารถยืนยันใบรับรองเหล่านี้ได้</translation>
<translation id="8790007591277257123">&amp;ทำซ้ำการนำออก</translation>
<translation id="8804164990146287819">นโยบายส่วนบุคคล</translation>
+<translation id="8820817407110198400">บุ๊กมาร์ก</translation>
<translation id="8824019021993735287">Chrome ไม่สามารถยืนยันบัตรของคุณได้ในขณะนี้ โปรดลองอีกครั้งในภายหลัง</translation>
<translation id="8834246243508017242">เปิดใช้การป้อนข้อความอัตโนมัติโดยใช้รายชื่อติดต่อ…</translation>
<translation id="883848425547221593">บุ๊กมาร์กอื่นๆ</translation>
+<translation id="884923133447025588">ไม่พบกระบวนการเพิกถอน</translation>
<translation id="8866481888320382733">ข้อผิดพลาดในการแยกวิเคราะห์การตั้งค่านโยบาย</translation>
<translation id="8876793034577346603">ไม่สามารถแยกวิเคราะห์การกำหนดค่าเครือข่าย</translation>
<translation id="8891727572606052622">โหมดพร็อกซีไม่ถูกต้อง</translation>
-<translation id="8940229512486821554">เรียกใช้คำสั่ง <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">ขออภัย การทดลองนี้ไม่สามารถใช้ได้กับแพลตฟอร์มของคุณ</translation>
+<translation id="8903921497873541725">ขยาย</translation>
+<translation id="8932102934695377596">นาฬิกาช้าเกินไป</translation>
+<translation id="8940229512486821554">เรียกใช้คำสั่ง <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">ใบรับรองของเซิร์ฟเวอร์หมดอายุแล้ว</translation>
<translation id="8988760548304185580">ป้อนวันหมดอายุและ CVC 3 หลักจากด้านหลังบัตร</translation>
-<translation id="9020542370529661692">หน้านี้ได้รับการแปลเป็น <ph name="TARGET_LANGUAGE"/> แล้ว</translation>
+<translation id="901974403500617787">การตั้งค่าสถานะที่ใช้ทั้งระบบสามารถตั้งค่าได้โดยเจ้าของเท่านั้น: <ph name="OWNER_EMAIL" /></translation>
+<translation id="9020542370529661692">หน้านี้ได้รับการแปลเป็น <ph name="TARGET_LANGUAGE" /> แล้ว</translation>
+<translation id="9049981332609050619">คุณพยายามเข้าถึง <ph name="DOMAIN" /> แต่เซิร์ฟเวอร์แสดงใบรับรองที่ไม่ถูกต้อง</translation>
<translation id="9125941078353557812">ป้อน CVC 3 หลักจากด้านหลังบัตร</translation>
<translation id="9137013805542155359">แสดงหน้าเว็บเดิม</translation>
<translation id="9148507642005240123">&amp;เลิกทำการแก้ไข</translation>
<translation id="9154176715500758432">อยู่ในหน้านี้</translation>
<translation id="9170848237812810038">เ&amp;ลิกทำ</translation>
+<translation id="917450738466192189">ใบรับรองของเซิร์ฟเวอร์ไม่ถูกต้อง</translation>
+<translation id="9187827965378254003">น่าเสียดาย ดูเหมือนว่าขณะนี้ยังไม่มีการทดลองแต่อย่างใด</translation>
<translation id="9207861905230894330">การเพิ่มบทความล้มเหลว</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ล้างฟอร์ม</translation>
+<translation id="988159990683914416">รุ่นนักพัฒนา</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_tr.xtb b/chromium/components/strings/components_strings_tr.xtb
index d2e7ad30de9..51653412d05 100644
--- a/chromium/components/strings/components_strings_tr.xtb
+++ b/chromium/components/strings/components_strings_tr.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="tr">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="tr">
+<translation id="1032854598605920125">Saat yönünde döndür</translation>
<translation id="1055184225775184556">Eklemeyi &amp;Geri Al</translation>
<translation id="106701514854093668">Masaüstü Yer İşaretleri</translation>
-<translation id="1103523840287552314"><ph name="LANGUAGE"/> dilini daima çevir</translation>
+<translation id="1080116354587839789">Genişliğe sığdır</translation>
+<translation id="1103523840287552314"><ph name="LANGUAGE" /> dilini daima çevir</translation>
<translation id="1113869188872983271">Sıralama değişikliğini &amp;geri al</translation>
<translation id="111844081046043029">Bu sayfadan ayrılmak istediğinizden emin misiniz?</translation>
<translation id="112840717907525620">Politika önbelleği uygun</translation>
<translation id="1132774398110320017">Chrome Otomatik Doldurma ayarları...</translation>
-<translation id="1152921474424827756"><ph name="URL"/> sitesinin <ph name="BEGIN_LINK"/>önbelleğe alınmış bir kopyasına<ph name="END_LINK"/> erişin</translation>
+<translation id="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="1152921474424827756"><ph name="URL" /> sitesinin <ph name="BEGIN_LINK" />önbelleğe alınmış bir kopyasına<ph name="END_LINK" /> erişin</translation>
+<translation id="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="1227224963052638717">Bilinmeyen politika.</translation>
<translation id="1227633850867390598">Değeri gizle</translation>
<translation id="1228893227497259893">Yanlış varlık tanımlayıcı</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Kayıt alan adı:</translation>
<translation id="1344588688991793829">Chromium Otomatik Doldurma ayarları...</translation>
<translation id="1426410128494586442">Evet</translation>
+<translation id="1430915738399379752">Yazdır</translation>
<translation id="1455235771979731432">Kartınız doğrulanırken bir sorun oluştu. İnternet bağlantınızı kontrol edin ve tekrar deneyin.</translation>
<translation id="1491151370853475546">Bu Sayfayı Yeniden Yükle</translation>
<translation id="1549470594296187301">Bu özelliğin kullanılabilmesi için JavaScript etkinleştirilmelidir.</translation>
-<translation id="1639239467298939599">Yükleniyor</translation>
<translation id="1640180200866533862">Kullanıcı politikaları</translation>
<translation id="1644184664548287040">Ağ yapılandırması geçersiz, dolayısıyla içe aktarılamadı.</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> web sitesindeki sayfanın mesajı:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikasının süresi dün sona erdi. Bu durum, bir yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. Bilgisayarınızın saati geçerli olarak <ph name="CURRENT_DATE" /> tarihine ayarlı. Bu ayar doğru görünüyor mu? Değilse, sisteminizin saatini düzeltmeli ve sonra bu sayfayı yenilemelisiniz.}other{Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası # gün önce sona erdi. Bu durum, bir yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. Bilgisayarınızın saati geçerli olarak <ph name="CURRENT_DATE" /> tarihine ayarlı. Bu ayar doğru görünüyor mu? Değilse, sisteminizin saatini düzeltmeli ve sonra bu sayfayı yenilemelisiniz.}}</translation>
+<translation id="168841957122794586">Sunucu sertifikasında zayıf bir şifreleme anahtarı var.</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> web sitesindeki sayfanın mesajı:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. cihazınızın işletim sistemi, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
<translation id="1821930232296380041">Geçersiz istek veya istek parametreleri</translation>
-<translation id="1853748787962613237">Makale görüntülenemedi.</translation>
<translation id="1871208020102129563">Proxy, bir .pac komut dosyası URL'sini değil, sabit proxy sunucuları kullanacak şekilde ayarlanır.</translation>
-<translation id="1875753206475436906">Sezgisel tür: <ph name="HEURISTIC_TYPE"/>
- sunucu türü: <ph name="SERVER_TYPE"/>
- alan imzası: <ph name="FIELD_SIGNATURE"/>
- form imzası: <ph name="FORM_SIGNATURE"/>
- deney kimliği: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158"><ph name="LINK"/> adresine git</translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> Yer İşaretleri</translation>
+<translation id="194030505837763158"><ph name="LINK" /> adresine git</translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> Yer İşaretleri</translation>
<translation id="1973335181906896915">Serileştirme hatası</translation>
+<translation id="1974060860693918893">Gelişmiş</translation>
<translation id="2025186561304664664">Proxy, otomatik yapılandırıldı değerine ayarlandı.</translation>
<translation id="2025623846716345241">Yeniden Yüklemeyi Onayla</translation>
-<translation id="2030481566774242610">Şunu mu demek istediniz?: <ph name="LINK"/></translation>
+<translation id="2030481566774242610">Şunu mu demek istediniz?: <ph name="LINK" /></translation>
<translation id="2053553514270667976">Posta kodu</translation>
<translation id="20817612488360358">Sistem proxy ayarları kullanılmak üzere ayarlandı, ancak açık bir proxy yapılandırması da belirtildi.</translation>
<translation id="2094505752054353250">Alan adı uyuşmazlığı</translation>
<translation id="2096368010154057602">Bölüm</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="2114841414352855701"><ph name="POLICY_NAME" /> tarafından geçersiz kılındığı için yoksayıldı.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Mobil Yer İşaretleri</translation>
+<translation id="2171101176734966184"><ph name="DOMAIN" /> adresine erişme girişiminde bulundunuz ancak sunucu zayıf bir imza algoritması kullanılarak imzalanmış bir sertifika sağladı. Bu, sunucunun sağladığı güvenlik bilgilerinin sahte olabileceği anlamına gelir ve sunucu sizin beklediğiniz sunucu olmayabilir (bir saldırgan ile irtibat kuruyor olabilirsiniz).</translation>
<translation id="2181821976797666341">Politikalar</translation>
<translation id="2212735316055980242">Politika bulunamadı</translation>
<translation id="2213606439339815911">Girişler getiriliyor...</translation>
<translation id="225207911366869382">Bu değer bu politika için kullanımdan kaldırıldı.</translation>
<translation id="2262243747453050782">HTTP hatası</translation>
-<translation id="2270192940992995399">Makale bulunamadı.</translation>
-<translation id="2328300916057834155"><ph name="ENTRY_INDEX"/> dizininde yok sayılan geçersiz yer işareti</translation>
+<translation id="2282872951544483773">Kullanılamayan Deneyler</translation>
+<translation id="229702904922032456">Bir kök ya da ara sertifikanın süresi geçmiş.</translation>
+<translation id="2328300916057834155"><ph name="ENTRY_INDEX" /> dizininde yok sayılan geçersiz yer işareti</translation>
<translation id="2354001756790975382">Diğer yer işaretleri</translation>
<translation id="2359808026110333948">Devam Et</translation>
<translation id="2367567093518048410">Düzey</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="2396249848217231973">Silmeyi &amp;geri al</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="2455981314101692989">Bu web sayfası bu form için otomatik doldurmayı devre dışı bıraktı.</translation>
<translation id="2479410451996844060">Geçersiz arama URL'si.</translation>
+<translation id="2491120439723279231">Sunucu sertifikası hatalar içeriyor.</translation>
<translation id="2495083838625180221">JSON Ayrıştırıcı</translation>
<translation id="2498091847651709837">Yeni kart tara</translation>
<translation id="2556876185419854533">Düzenlemeyi &amp;Geri Al</translation>
-<translation id="2581221116934462656"><ph name="PRODUCT_NAME"/> ürününün bir dahaki sefere <ph name="LANGUAGE_NAME"/> sayfaları çevirmeyi teklif etmesini ister misiniz?</translation>
+<translation id="2581221116934462656"><ph name="PRODUCT_NAME" /> ürününün bir dahaki sefere <ph name="LANGUAGE_NAME" /> sayfaları çevirmeyi teklif etmesini ister misiniz?</translation>
<translation id="2587841377698384444">Dizin API'sı Kimliği:</translation>
<translation id="2597378329261239068">Doküman şifre korumalı. Lütfen şifreyi girin.</translation>
+<translation id="2625385379895617796">Saatiniz ileri</translation>
<translation id="2639739919103226564">Durum:</translation>
+<translation id="2653659639078652383">Gönder</translation>
<translation id="2704283930420550640">Değer, biçimle eşleşmiyor.</translation>
<translation id="2721148159707890343">İstek başarılı oldu</translation>
+<translation id="2728127805433021124">Sunucunun sertifikası, zayıf bir imza algoritması kullanılarak imzalanmış.</translation>
<translation id="2774256287122201187">Devam edebilirsiniz. Söz konusu sayfaya devam ederseniz bu uyarı beş dakika boyunca bir daha görünmez.</translation>
<translation id="277499241957683684">Eksik cihaz kaydı</translation>
<translation id="2835170189407361413">Formu temizle</translation>
-<translation id="2855922900409897335"><ph name="CREDIT_CARD"/> kredi kartınızı doğrulayın</translation>
+<translation id="2855922900409897335"><ph name="CREDIT_CARD" /> kredi kartınızı doğrulayın</translation>
+<translation id="2915500479781995473">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikasının süresi dolmuş. Bu durum, bir yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. Bilgisayarınızın saati şu anda <ph name="CURRENT_TIME" /> değerine ayarlı. Saat doğru mu? Değilse sistem saatinizi düzeltmeniz ve ardından bu sayfayı yenilemeniz gerekir.</translation>
+<translation id="2922350208395188000">Sunucunun sertifikası kontrol edilemiyor.</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="2958431318199492670">Ağ yapılandırması ONC standardıyla uyumlu değil. Yapılandırmanın bazı bölümleri içe aktarılamaz.</translation>
<translation id="2972581237482394796">&amp;Yinele</translation>
-<translation id="3010559122411665027">Liste girişi &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Liste girişi "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Yanlış politika türü</translation>
<translation id="3105172416063519923">Öğe Kimliği:</translation>
<translation id="3145945101586104090">Yanıtın kodu çözülemedi</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Bul</translation>
<translation id="3174168572213147020">Ada</translation>
<translation id="3219579145727097045">Son kullanma tarihini ve kartınızın önündeki 4 basamaklı CVC'yi girin</translation>
-<translation id="3228969707346345236">Sayfa zaten <ph name="LANGUAGE"/> dilinde olduğundan çeviri işlemi başarısız oldu.</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="3228969707346345236">Sayfa zaten <ph name="LANGUAGE" /> dilinde olduğundan çeviri işlemi başarısız oldu.</translation>
<translation id="3270847123878663523">Sıralama Değişikliğini &amp;Geri Al</translation>
+<translation id="3286538390144397061">Şimdi yeniden başlat</translation>
<translation id="333371639341676808">Bu sayfanın ek iletişim kutusu oluşturmasına izin verme.</translation>
-<translation id="3369366829301677151"><ph name="CREDIT_CARD"/> kredi kartınızı güncelleyin ve doğrulayın</translation>
+<translation id="3340978935015468852">ayarlar</translation>
+<translation id="3369192424181595722">Saat hatası</translation>
+<translation id="3369366829301677151"><ph name="CREDIT_CARD" /> kredi kartınızı güncelleyin ve doğrulayın</translation>
<translation id="337363190475750230">Temel hazırlık iptal edildi</translation>
<translation id="3377188786107721145">Politika ayrıştırma hatası</translation>
<translation id="3380365263193509176">Bilinmeyen hata</translation>
<translation id="3380864720620200369">İstemci Kimliği:</translation>
<translation id="3427342743765426898">&amp;Düzenlemeyi Yeniden Yap</translation>
+<translation id="3435896845095436175">Etkinleştir</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Getirme aralığı:</translation>
+<translation id="3462200631372590220">Gelişmiş bilgileri gizle</translation>
+<translation id="3528171143076753409">Sunucunun sertifikasına güvenilmiyor.</translation>
<translation id="3542684924769048008">Şunun için şifre kullan:</translation>
<translation id="3583757800736429874">Taşımayı &amp;Yeniden Yap</translation>
<translation id="3623476034248543066">Değeri göster</translation>
+<translation id="3648607100222897006">Bu deneysel özellikler zaman zaman değişebilir, bozulabilir veya kullanımdan kaldırılabilir. Bu deneylerden herhangi birini açtığınızda tarayıcınızın aniden yanmaya başlaması mümkün olduğundan, başınıza gelebilecekler konusunda kesinlikle hiçbir garanti vermeyiz. Şaka bir yana, tarayıcınız tüm verilerinizi silebilir ya da güvenliğiniz ve gizliliğiniz beklenmedik şekillerde riske girebilir. Etkinleştireceğiniz her deney bu tarayıcının tüm kullanıcıları için etkin hale gelecektir. Lütfen dikkatle ilerleyin.</translation>
<translation id="3650584904733503804">Doğrulama başarılı</translation>
<translation id="370665806235115550">Yükleniyor...</translation>
<translation id="3712624925041724820">Lisanslar bitti</translation>
<translation id="3739623965217189342">Kopyaladığınız bağlantı</translation>
<translation id="375403751935624634">Çeviri, bir sunucu hatası nedeniyle başarısız oldu.</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>
<translation id="3885155851504623709">Bucak</translation>
<translation id="3934680773876859118">PDF dokümanı yüklenemedi</translation>
<translation id="3963721102035795474">Okuyucu Modu</translation>
<translation id="4030383055268325496">Eklemeyi &amp;geri al</translation>
-<translation id="4058922952496707368">&quot;<ph name="SUBKEY"/>&quot; anahtarı: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">UYARI</translation>
+<translation id="4058922952496707368">"<ph name="SUBKEY" />" anahtarı: <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Proxy yapılandırması sabit proxy sunucuları değil, bir .pac komut dosyası URL'sini kullanmak üzere ayarlandı.</translation>
<translation id="409504436206021213">Yeniden Yükleme</translation>
<translation id="4103249731201008433">Cihazın seri numarası geçersiz</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">İmza yanlış</translation>
<translation id="4269787794583293679">(Kullanıcı adı yok)</translation>
<translation id="4300246636397505754">Ebeveyn önerileri</translation>
-<translation id="4372948949327679948">Beklenen <ph name="VALUE_TYPE"/> değeri.</translation>
+<translation id="4325863107915753736">Makale bulunamadı</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="4394049700291259645">Devre dışı bırak</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="443673843213245140">Proxy kullanımı devre dışı, ancak açık bir proxy yapılandırması belirtildi.</translation>
-<translation id="4506176782989081258">Doğrulama hatası: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Doğrulama hatası: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Adres Chrome'dan kaldırılsın mı?</translation>
<translation id="4594403342090139922">Silmeyi &amp;Geri Al</translation>
<translation id="4607653538520819196">Veri Tasarrufu bu sayfaya proxy uygulayamıyor.</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="4726672564094551039">Politikaları yeniden yükle</translation>
+<translation id="4728558894243024398">Platform</translation>
+<translation id="4771973620359291008">Bilinmeyen bir hata oluştu.</translation>
<translation id="4800132727771399293">Son kullanma tarihinizi ve CVC'nizi kontrol edip tekrar deneyin</translation>
<translation id="4813512666221746211">Ağ hatası</translation>
+<translation id="4816492930507672669">Sayfaya sığdır</translation>
<translation id="4850886885716139402">Görüntüle</translation>
-<translation id="4923417429809017348">Bu sayfa, bilinmeyen bir dilden <ph name="LANGUAGE_LANGUAGE"/> diline çevrildi</translation>
+<translation id="4923417429809017348">Bu sayfa, bilinmeyen bir dilden <ph name="LANGUAGE_LANGUAGE" /> diline çevrildi</translation>
<translation id="4926049483395192435">Belirtilmelidir.</translation>
<translation id="4968547170521245791">Proxy uygulayamıyor</translation>
-<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE"/> dilinden <ph name="TARGET_LANGUAGE"/> diline çevrilsin mi?</translation>
+<translation id="498957508165411911"><ph name="ORIGINAL_LANGUAGE" /> dilinden <ph name="TARGET_LANGUAGE" /> diline çevrilsin mi?</translation>
<translation id="5019198164206649151">Yedekleme deposu kötü durumda</translation>
<translation id="5031870354684148875">Google Çeviri Hakkında</translation>
+<translation id="5045550434625856497">Yanlış şifre</translation>
+<translation id="5087286274860437796">Sunucu sertifikası şu anda geçerli değil.</translation>
<translation id="5089810972385038852">Eyalet</translation>
+<translation id="5094747076828555589">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı; Chromium, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
<translation id="5095208057601539847">Bölge</translation>
<translation id="5145883236150621069">Politika yanıtında hata kodu var</translation>
<translation id="5172758083709347301">Makine</translation>
-<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE"/> dilinde değil mi? Bu hatayı bildirin</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="5199729219167945352">Deneyler</translation>
+<translation id="5251803541071282808">Bulut</translation>
<translation id="5295309862264981122">Gezintiyi Onayla</translation>
<translation id="5299298092464848405">Politika ayrıştırma hatası</translation>
+<translation id="5316812925700871227">Saat yönünün tersine döndür</translation>
<translation id="5317780077021120954">Kaydet</translation>
<translation id="536296301121032821">Politika ayarları saklanamadı</translation>
-<translation id="5439770059721715174">&quot;<ph name="ERROR_PATH"/>&quot; üzerinde şema doğrulama hatası: <ph name="ERROR"/></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="5439770059721715174">"<ph name="ERROR_PATH" />" üzerinde şema doğrulama hatası: <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Politika zaman damgası yanlış</translation>
<translation id="5470861586879999274">Düzenlemeyi &amp;yeniden yap</translation>
<translation id="5509780412636533143">Yönetilen yer işaretleri</translation>
<translation id="5523118979700054094">Politika adı</translation>
<translation id="552553974213252141">Metin doğru bir şekilde çıkarıldı mı?</translation>
<translation id="5540224163453853">İstenen makale bulunamadı.</translation>
+<translation id="5556459405103347317">Yeniden Yükle</translation>
<translation id="5565735124758917034">Etkin</translation>
<translation id="560412284261940334">Yönetim desteklenmiyor</translation>
<translation id="5629630648637658800">Politika ayarları yüklenemedi</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Geçerli kullanıcı</translation>
<translation id="5813119285467412249">Eklemeyi &amp;Yeniden Yap</translation>
<translation id="5872918882028971132">Ebeveyn Önerileri</translation>
-<translation id="587701087903783706">Mobil uyumlu görünümü kapat</translation>
<translation id="59107663811261420">Google Payments, bu satıcı için bu kart türünü desteklememektedir. Lütfen farklı bir kart seçin.</translation>
+<translation id="5975083100439434680">Uzaklaştır</translation>
<translation id="5989320800837274978">Sabit proxy sunucular veya bir .pac komut dosyası URL'si belirtilmedi.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Kapat</translation>
+<translation id="6060685159320643512">Dikkatli olun, bu deneyler canınızı yakabilir</translation>
+<translation id="6151417162996330722">Sunucu sertifikasının geçerlilik dönemi çok uzun.</translation>
<translation id="6154808779448689242">Döndürülen politika jetonu mevcut jetondan farklı</translation>
<translation id="6165508094623778733">Daha fazla bilgi edinin</translation>
<translation id="6259156558325130047">Sıralama Değişikliğini &amp;Yeniden Yap</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> yer işaretleri</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> yer işaretleri</translation>
<translation id="6282194474023008486">Posta kodu</translation>
<translation id="6337534724793800597">Politikalara ada göre filtre uygula</translation>
+<translation id="6387478394221739770">Chrome'daki etkileyici, yeni özellikler ilginizi çekiyor mu? chrome.com/beta adresinden beta kanalımızı deneyin.</translation>
+<translation id="6426993025560594914">Tüm denemeler platformunuzda kullanılabilir!</translation>
<translation id="6445051938772793705">Ülke</translation>
<translation id="6458467102616083041">Varsayılan arama politika tarafından devre dışı bırakıldığı için yoksayıldı.</translation>
<translation id="647261751007945333">Cihaz politikaları</translation>
<translation id="6512448926095770873">Bu Sayfadan Ayrıl</translation>
<translation id="6529602333819889595">Silmeyi &amp;Yeniden Yap</translation>
<translation id="6550675742724504774">Seçenekler</translation>
-<translation id="6597614308054261376"><ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/> sitesine ulaşmaya çalışıyorsunuz. Şu anda bu sayfaya Veri Tasarrufu tarafından proxy uygulanamıyor.</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> Arama</translation>
+<translation id="6597614308054261376"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesine ulaşmaya çalışıyorsunuz. Şu anda bu sayfaya Veri Tasarrufu tarafından proxy uygulanamıyor.</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> Arama</translation>
<translation id="6644283850729428850">Bu politika uygun bulunmadı.</translation>
<translation id="6646897916597483132">Kartınızın önündeki 4 basamaklı CVC'yi girin</translation>
+<translation id="674375294223700098">Bilinmeyen sunucu sertifikası hatası.</translation>
<translation id="6753269504797312559">Politika değeri</translation>
<translation id="6831043979455480757">Çevir</translation>
<translation id="6839929833149231406">Bölge</translation>
<translation id="6874604403660855544">Eklemeyi &amp;yeniden yap</translation>
<translation id="6891596781022320156">Politika düzeyi desteklenmiyor.</translation>
<translation id="6915804003454593391">Kullanıcı:</translation>
+<translation id="6957887021205513506">Sunucunun sertifikası sahte görünüyor.</translation>
<translation id="6965382102122355670">Tamam</translation>
<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="6980028882292583085">JavaScript Uyarısı</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250"><ph name="DOMAIN" /> alan adına erişmeyi denediniz, ancak sunucu, geçerlilik dönemi güvenilir olmayacak kadar uzun olan bir sertifika sundu.</translation>
<translation id="7087282848513945231">İlçe</translation>
-<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE"/> diline çeviri başarısız oldu.</translation>
+<translation id="7108649287766967076"><ph name="TARGET_LANGUAGE" /> diline çeviri başarısız oldu.</translation>
<translation id="7139724024395191329">Emirlik</translation>
+<translation id="7179921470347911571">Şimdi Yeniden Başlat</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="7186367841673660872">Bu sayfa,<ph name="ORIGINAL_LANGUAGE" />dilinden<ph name="LANGUAGE_LANGUAGE" />diline çevrilmiştir</translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531"><ph name="SITE_NAME"/> sitesinde <ph name="SEARCH_TERMS"/> terimlerini ara</translation>
+<translation id="7208899522964477531"><ph name="SITE_NAME" /> sitesinde <ph name="SEARCH_TERMS" /> terimlerini ara</translation>
+<translation id="725866823122871198">Bilgisayarınızın tarih ve saati (<ph name="DATE_AND_TIME" />) yanlış olduğundan <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> alan adına gizli bir bağlantı kurulamıyor.</translation>
<translation id="7275334191706090484">Yönetilen Yer İşaretleri</translation>
<translation id="7298195798382681320">Önerilenler</translation>
<translation id="7334320624316649418">Sıralama değişikliğini &amp;yeniden yap</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Zorunlu</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="7568593326407688803">Bu sayfanın dili<ph name="ORIGINAL_LANGUAGE"/>Çevrilmesini istiyor musunuz?</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="7568593326407688803">Bu sayfanın dili<ph name="ORIGINAL_LANGUAGE" />Çevrilmesini istiyor musunuz?</translation>
<translation id="7569952961197462199">Kredi kartı Chrome'dan kaldırılsın mı?</translation>
-<translation id="7600965453749440009"><ph name="LANGUAGE"/> dilini asla çevirme</translation>
-<translation id="7610193165460212391">Değer aralık dışında: <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Sunucunun sertifikası ad sınırlamasını ihlal ediyor.</translation>
+<translation id="7600965453749440009"><ph name="LANGUAGE" /> dilini asla çevirme</translation>
+<translation id="7610193165460212391">Değer aralık dışında: <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Chrome'daki etkileyici, yeni özellikler ilginizi çekiyor mu? chrome.com/dev adresinden geliştirici kanalımızı deneyin.</translation>
<translation id="7752995774971033316">Yönetimden kaldırıldı</translation>
+<translation id="7761701407923456692">Sunucu sertifikası URL ile eşleşmiyor.</translation>
<translation id="777702478322588152">İdari bölge</translation>
<translation id="7791543448312431591">Ekle</translation>
<translation id="7805768142964895445">Durum</translation>
<translation id="7813600968533626083">Form önerisi Chrome'dan kaldırılsın mı?</translation>
<translation id="7887683347370398519">CVC'nizi kontrol edin ve tekrar deneyin</translation>
<translation id="7935318582918952113">DOM Ayrıştırıcı</translation>
+<translation id="7938958445268990899">Sunucunun sertifikası henüz geçerli değil.</translation>
<translation id="7956713633345437162">Mobil yer işaretleri</translation>
<translation id="7961015016161918242">Hiçbir Zaman</translation>
<translation id="7977590112176369853">&lt;sorgu girin&gt;</translation>
-<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE"/> dilini her zaman <ph name="TARGET_LANGUAGE"/> diline çevir</translation>
+<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE" /> dilini her zaman <ph name="TARGET_LANGUAGE" /> diline çevir</translation>
<translation id="7988324688042446538">Masaüstü yer işaretleri</translation>
<translation id="7995512525968007366">Belirtilmedi</translation>
-<translation id="8034522405403831421">Bu sayfa <ph name="SOURCE_LANGUAGE"/> dilinde. <ph name="TARGET_LANGUAGE"/> diline çevrilsin mi?</translation>
+<translation id="8003882219468422867">Kuruluş tarafından geçersiz kılma</translation>
+<translation id="8034522405403831421">Bu sayfa <ph name="SOURCE_LANGUAGE" /> dilinde. <ph name="TARGET_LANGUAGE" /> diline çevrilsin mi?</translation>
<translation id="8088680233425245692">Makale görüntülenemedi.</translation>
<translation id="8091372947890762290">Etkinleştirme sunucuda bekliyor</translation>
<translation id="8194797478851900357">Taşımayı &amp;Geri Al</translation>
-<translation id="8201077131113104583">&quot;<ph name="EXTENSION_ID"/>&quot; kodlu uzantı için geçersiz güncelleme URL'si.</translation>
+<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" kodlu uzantı için geçersiz güncelleme URL'si.</translation>
<translation id="8208216423136871611">Kaydetme</translation>
<translation id="8218327578424803826">Atanan Konum:</translation>
<translation id="8249320324621329438">Son getirilen:</translation>
+<translation id="8294431847097064396">Kaynak</translation>
<translation id="8308427013383895095">Ağ bağlantısıyla ilgili bir sorun nedeniyle çeviri başarısız oldu.</translation>
<translation id="8311778656528046050">Bu sayfayı yeniden yüklemek istediğinizden emin misiniz?</translation>
<translation id="8349305172487531364">Yer işaretleri çubuğu</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Uygulandığı yer</translation>
<translation id="8530504477309582336">Google Payments, bu kart türünü desteklememektedir. Lütfen farklı bir kart seçin.</translation>
<translation id="8553075262323480129">Sayfanın dili belirlenemediğinden çeviri başarısız oldu.</translation>
-<translation id="8571890674111243710">Sayfa <ph name="LANGUAGE"/> diline çevriliyor...</translation>
+<translation id="8559762987265718583">Cihazınızın tarih ve saati (<ph name="DATE_AND_TIME" />) yanlış olduğundan <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> alan adına gizli bir bağlantı kurulamıyor.</translation>
+<translation id="8571890674111243710">Sayfa <ph name="LANGUAGE" /> diline çevriliyor...</translation>
+<translation id="8647750283161643317">Tümünü varsayılan değerlere sıfırla</translation>
<translation id="8713130696108419660">Başlangıç anahtarlı imza bozuk</translation>
<translation id="8725066075913043281">Yeniden dene</translation>
+<translation id="8738058698779197622">Güvenli bir bağlantı kurmak için saatinizin doğru ayarlanmış olması gerekir. Bunun sebebi, web sitelerinin kendilerini tanımlamak için kullandıkları sertifikaların sadece belli süreler için geçerli olmasıdır. Cihazınızın saati yanlış olduğundan, Chromium bu sertifikaları doğrulayamaz.</translation>
<translation id="8790007591277257123">Silmeyi &amp;yeniden yap</translation>
<translation id="8804164990146287819">Gizlilik Politikası</translation>
+<translation id="8820817407110198400">Favoriler</translation>
<translation id="8824019021993735287">Chrome, şu anda kartınızı doğrulayamıyor. Lütfen daha sonra tekrar deneyin.</translation>
<translation id="8834246243508017242">Kişiler'i kullanarak Otomatik Doldur'u etkinleştir…</translation>
<translation id="883848425547221593">Diğer Yer İşaretleri</translation>
+<translation id="884923133447025588">İptal mekanizması bulunamadı.</translation>
<translation id="8866481888320382733">Politika ayarlarını ayrıştırma hatası</translation>
<translation id="8876793034577346603">Ağ yapılandırması ayrıştırılamadı.</translation>
<translation id="8891727572606052622">Geçersiz proxy modu.</translation>
-<translation id="8940229512486821554"><ph name="EXTENSION_NAME"/> komutunu çalıştır: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Maalesef bu deney platformunuzda kullanılamıyor.</translation>
+<translation id="8903921497873541725">Yakınlaştır</translation>
+<translation id="8932102934695377596">Saatiniz geri</translation>
+<translation id="8940229512486821554"><ph name="EXTENSION_NAME" /> komutunu çalıştır: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Sunucu sertifikasının süresi doldu.</translation>
<translation id="8988760548304185580">Son kullanma tarihini ve kartınızın arkasındaki 3 basamaklı CVC'yi girin</translation>
-<translation id="9020542370529661692">Bu sayfa <ph name="TARGET_LANGUAGE"/> diline çevrildi</translation>
+<translation id="901974403500617787">Tüm sistem için geçerli olan işaretler sadece sahibi <ph name="OWNER_EMAIL" /> tarafından ayarlanabilir.</translation>
+<translation id="9020542370529661692">Bu sayfa <ph name="TARGET_LANGUAGE" /> diline çevrildi</translation>
+<translation id="9049981332609050619"><ph name="DOMAIN" /> alan adına erişmeye çalıştınız, ancak sunucu geçersiz bir sertifika sağladı.</translation>
<translation id="9125941078353557812">Kartınızın arkasındaki 3 basamaklı CVC'yi girin</translation>
<translation id="9137013805542155359">Orijinali göster</translation>
<translation id="9148507642005240123">Düzenlemeyi &amp;geri al</translation>
<translation id="9154176715500758432">Bu Sayfada Kal</translation>
<translation id="9170848237812810038">&amp;Geri al</translation>
+<translation id="917450738466192189">Sunucunun sertifikası geçersiz.</translation>
+<translation id="9187827965378254003">Maalesef, görünüşe göre şu anda kullanılabilir deney yok.</translation>
<translation id="9207861905230894330">Makale eklenemedi.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">FORMU TEMİZLE</translation>
+<translation id="988159990683914416">Geliştirici Derlemesi</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_uk.xtb b/chromium/components/strings/components_strings_uk.xtb
index d6fcbec7323..1e15aebed77 100644
--- a/chromium/components/strings/components_strings_uk.xtb
+++ b/chromium/components/strings/components_strings_uk.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="uk">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="uk">
+<translation id="1032854598605920125">Обернути за годинниковою стрілкою</translation>
<translation id="1055184225775184556">&amp;Відмінити додавання</translation>
<translation id="106701514854093668">Закладки для настільного комп’ютера</translation>
-<translation id="1103523840287552314">Завжди перекладати з такої мови: <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">За шириною сторінки</translation>
+<translation id="1103523840287552314">Завжди перекладати з такої мови: <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Відмінити перевпорядкування</translation>
<translation id="111844081046043029">Дійсно залишити цю сторінку?</translation>
<translation id="112840717907525620">Кеш-пам’ять правила не пошкоджено</translation>
<translation id="1132774398110320017">Налаштування автозаповнення Chrome…</translation>
-<translation id="1152921474424827756">Відкрийте <ph name="BEGIN_LINK"/>кешовану копію<ph name="END_LINK"/> <ph name="URL"/></translation>
+<translation id="1150979032973867961">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Операційна система вашого комп’ютера не вважає його сертифікат безпеки надійним. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
+<translation id="1152921474424827756">Відкрийте <ph name="BEGIN_LINK" />кешовану копію<ph name="END_LINK" /> <ph name="URL" /></translation>
+<translation id="121201262018556460">Ви пробували зв’язатися з доменом <ph name="DOMAIN" />, проте сервер надав сертифікат, який містить слабкий ключ. Можливо, зловмисник зламав секретний ключ, а сервер не є тим, який вам потрібен (ви можете обмінюватися даними зі зловмисником).</translation>
<translation id="1227224963052638717">Невідоме правило</translation>
<translation id="1227633850867390598">Сховати значення</translation>
<translation id="1228893227497259893">Неправильний ідентифікатор організації</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Домен реєстрації:</translation>
<translation id="1344588688991793829">Налаштування автозаповнення Chromium…</translation>
<translation id="1426410128494586442">так</translation>
+<translation id="1430915738399379752">Друк</translation>
<translation id="1455235771979731432">Не вдалося підтвердити дані картки. Перевірте з’єднання з Інтернетом і повторіть спробу.</translation>
<translation id="1491151370853475546">Перезавантажити цю сторінку</translation>
<translation id="1549470594296187301">Щоб користуватися цією функцією, потрібно ввімкнути JavaScript.</translation>
-<translation id="1639239467298939599">Завантаження</translation>
<translation id="1640180200866533862">Правила користувача</translation>
<translation id="1644184664548287040">Конфігурація мережі недійсна та не може імпортуватися.</translation>
-<translation id="1693754753824026215">Повідомлення від сторінки <ph name="SITE"/>:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Не вдалося підтвердити, що це сервер <ph name="DOMAIN" />. Його сертифікат перестав діяти учора. Можливо, сервер налаштовано неправильно або хтось намагається перехопити ваші дані. На годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте системний годинник і оновіть цю сторінку.}one{Не вдалося підтвердити, що це сервер <ph name="DOMAIN" />. Його сертифікат перестав діяти # день тому. Можливо, сервер налаштовано неправильно або хтось намагається перехопити ваші дані. На годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте системний годинник і оновіть цю сторінку.}few{Не вдалося підтвердити, що це сервер <ph name="DOMAIN" />. Його сертифікат перестав діяти # дні тому. Можливо, сервер налаштовано неправильно або хтось намагається перехопити ваші дані. На годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте системний годинник і оновіть цю сторінку.}many{Не вдалося підтвердити, що це сервер <ph name="DOMAIN" />. Його сертифікат перестав діяти # днів тому. Можливо, сервер налаштовано неправильно або хтось намагається перехопити ваші дані. На годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте системний годинник і оновіть цю сторінку.}other{Не вдалося підтвердити, що це сервер <ph name="DOMAIN" />. Його сертифікат перестав діяти # дня тому. Можливо, сервер налаштовано неправильно або хтось намагається перехопити ваші дані. На годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте системний годинник і оновіть цю сторінку.}}</translation>
+<translation id="168841957122794586">Сертифікат сервера містить слабкий криптографічний ключ.</translation>
+<translation id="1693754753824026215">Повідомлення від сторінки <ph name="SITE" />:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Операційна система вашого пристрою не вважає його сертифікат безпеки надійним. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
<translation id="1821930232296380041">Недійсний запит або параметри запиту</translation>
-<translation id="1853748787962613237">Не вдалося показати статтю.</translation>
<translation id="1871208020102129563">Проксі-сервер налаштовано на використання фіксованих проксі-серверів, а не URL-адреси сценарію .pac.</translation>
-<translation id="1875753206475436906">евристичний тип: <ph name="HEURISTIC_TYPE"/>
- тип сервера: <ph name="SERVER_TYPE"/>
- сигнатура поля: <ph name="FIELD_SIGNATURE"/>
- сигнатура форми: <ph name="FORM_SIGNATURE"/>
- експериментальний ідентифікатор: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Перейдіть за адресою <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Закладки <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Перейдіть за адресою <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Закладки <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Помилка серіалізації</translation>
+<translation id="1974060860693918893">Розширені</translation>
<translation id="2025186561304664664">Проксі-сервер установлено на автоматичне налаштування.</translation>
<translation id="2025623846716345241">Підтвердьте перезавантаження</translation>
-<translation id="2030481566774242610">Можливо, ви мали на увазі <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Можливо, ви мали на увазі <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Поштовий індекс</translation>
<translation id="20817612488360358">Системні параметри проксі-сервера налаштовано для використання, але чітко вказано налаштування проксі-сервера.</translation>
<translation id="2094505752054353250">Невідповідність домену</translation>
<translation id="2096368010154057602">Департамент</translation>
<translation id="2113977810652731515">Картка</translation>
-<translation id="2114841414352855701">Правило ігнорується, оскільки його замінено правилом <ph name="POLICY_NAME"/>.</translation>
+<translation id="2114841414352855701">Правило ігнорується, оскільки його замінено правилом <ph name="POLICY_NAME" />.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Закладки для мобільних пристроїв</translation>
+<translation id="2171101176734966184">Ви пробували зв’язатися з доменом <ph name="DOMAIN" />, проте сервер надав сертифікат, підписаний із використанням слабкого алгоритму підпису. Це означає, що облікові дані системи захисту, надані сервером, можуть бути сфальсифікованими, а сервер – не тим, який вам потрібен (можливо, ви обмінюєтеся даними зі зловмисником).</translation>
<translation id="2181821976797666341">Правила</translation>
<translation id="2212735316055980242">Правило не знайдено</translation>
<translation id="2213606439339815911">Отримання записів…</translation>
<translation id="225207911366869382">Дію цього значення припинено для цього правила</translation>
<translation id="2262243747453050782">Помилка HTTP</translation>
-<translation id="2270192940992995399">Не вдалося знайти статтю.</translation>
-<translation id="2328300916057834155">Недійсна закладка в індексі <ph name="ENTRY_INDEX"/> ігнорується</translation>
+<translation id="2282872951544483773">Недоступні експериментальні функції</translation>
+<translation id="229702904922032456">Термін дії кореневого або проміжного сертифіката закінчився.</translation>
+<translation id="2328300916057834155">Недійсна закладка в індексі <ph name="ENTRY_INDEX" /> ігнорується</translation>
<translation id="2354001756790975382">Інші закладки</translation>
<translation id="2359808026110333948">Продовжити</translation>
<translation id="2367567093518048410">Рівень</translation>
+<translation id="2384307209577226199">Стандартне корпоративне правило</translation>
+<translation id="2386255080630008482">Сертифікат сервера відкликано.</translation>
<translation id="2392959068659972793">Показувати правила, для яких не встановлено значення</translation>
<translation id="2396249848217231973">&amp;Відмінити видалення</translation>
+<translation id="2413528052993050574">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Можливо, його сертифікат безпеки відкликано. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
<translation id="2455981314101692989">На цій веб-сторінці вимкнено автоматичне заповнення цієї форми.</translation>
<translation id="2479410451996844060">Недійсна URL-адреса для пошуку.</translation>
+<translation id="2491120439723279231">Сертифікат сервера містить помилки.</translation>
<translation id="2495083838625180221">Синтаксичний аналізатор файлів JSON</translation>
<translation id="2498091847651709837">Сканувати нову картку</translation>
<translation id="2556876185419854533">&amp;Відмінити редагування</translation>
-<translation id="2581221116934462656">Хочете, щоб наступного разу <ph name="PRODUCT_NAME"/> пропонував перекласти сторінки цього сайту, написані такою мовою: <ph name="LANGUAGE_NAME"/>?</translation>
+<translation id="2581221116934462656">Хочете, щоб наступного разу <ph name="PRODUCT_NAME" /> пропонував перекласти сторінки цього сайту, написані такою мовою: <ph name="LANGUAGE_NAME" />?</translation>
<translation id="2587841377698384444">Ідентифікатор API каталогу:</translation>
<translation id="2597378329261239068">Цей документ захищено паролем. Введіть пароль.</translation>
+<translation id="2625385379895617796">Ваш годинник спішить</translation>
<translation id="2639739919103226564">Статус:</translation>
+<translation id="2653659639078652383">Надіслати</translation>
<translation id="2704283930420550640">Значення не відповідає формату.</translation>
<translation id="2721148159707890343">Запит надіслано</translation>
+<translation id="2728127805433021124">Сертифікат сервера підписано з використанням слабкого алгоритму підпису.</translation>
<translation id="2774256287122201187">Можна продовжити. Якщо перейти на сторінку, це попередження не відображатиметься протягом п’яти хвилин.</translation>
<translation id="277499241957683684">Відсутній запис пристрою</translation>
<translation id="2835170189407361413">Очистити форму</translation>
-<translation id="2855922900409897335">Підтвердьте дані своєї картки <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">Підтвердьте дані своєї картки <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">Серверу не вдалося підтвердити, що це <ph name="DOMAIN" />. Термін дії сертифіката безпеки цього домену закінчився. Можливі причини: неправильна конфігурація або перехоплення вашого з’єднання зловмисником. На годиннику вашого комп’ютера зараз <ph name="CURRENT_TIME" />. Якщо дата неправильна, налаштуйте системний годинник і оновіть цю сторінку.</translation>
+<translation id="2922350208395188000">Сертифікат сервера неможливо перевірити.</translation>
+<translation id="2941952326391522266">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Його сертифікат безпеки походить із домену <ph name="DOMAIN2" />. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
<translation id="2958431318199492670">Конфігурація мережі не відповідає стандарту ONC. Вона може імпортуватися частково.</translation>
<translation id="2972581237482394796">&amp;Повторити</translation>
-<translation id="3010559122411665027">Елемент списку &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Елемент списку "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Неправильний тип правила</translation>
<translation id="3105172416063519923">Ідентифікатор об’єкта:</translation>
<translation id="3145945101586104090">Помилка декодування відповіді</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Острів</translation>
<translation id="3219579145727097045">Введіть дату закінчення терміну дії та код CVC з 4 цифр, розташований на звороті вашої картки</translation>
-<translation id="3228969707346345236">Помилка перекладу. Сторінку вже перекладено такою мовою: <ph name="LANGUAGE"/>.</translation>
+<translation id="3225919329040284222">Сервер надав сертифікат, який не відповідає очікуваним вбудованим параметрам. Ці очікувані параметри встановлено для певних веб-сайтів із високим рівнем безпеки, щоб захистити вас.</translation>
+<translation id="3228969707346345236">Помилка перекладу. Сторінку вже перекладено такою мовою: <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Відмінити перевпорядкування</translation>
+<translation id="3286538390144397061">Перезапустити зараз</translation>
<translation id="333371639341676808">Заборонити створення додаткових діалогових вікон цією сторінкою.</translation>
-<translation id="3369366829301677151">Оновіть і підтвердьте дані своєї картки <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">налаштування</translation>
+<translation id="3369192424181595722">Помилка годинника</translation>
+<translation id="3369366829301677151">Оновіть і підтвердьте дані своєї картки <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">Деініціалізовано</translation>
<translation id="3377188786107721145">Помилка аналізу правила</translation>
<translation id="3380365263193509176">Невідома помилка</translation>
<translation id="3380864720620200369">Ідентифікатор клієнта:</translation>
<translation id="3427342743765426898">&amp;Повторити редагування</translation>
+<translation id="3435896845095436175">Увімкнути</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Інтервал отримання:</translation>
+<translation id="3462200631372590220">Сховати додаткову інформацію</translation>
+<translation id="3528171143076753409">Сертифікат сервера ненадійний.</translation>
<translation id="3542684924769048008">Використовувати пароль для:</translation>
<translation id="3583757800736429874">&amp;Повторити переміщення</translation>
<translation id="3623476034248543066">Показати значення</translation>
+<translation id="3648607100222897006">Ці експериментальні функції можуть будь-коли змінюватися, виходити з ладу чи зникати. Ми не даємо жодних гарантій щодо можливих наслідків увімкнення однієї з цих експериментальних функцій, а ваш веб-переглядач може навіть раптово припинити роботу. Ваш веб-переглядач може видалити всі ваші дані, а вашу безпеку та конфіденційність може бути порушено неочікуваним чином. Будь-які ввімкнені вами експериментальні функції буде ввімкнено для всіх користувачів цього веб-переглядача. Застосовуйте з обережністю.</translation>
<translation id="3650584904733503804">Перевірку закінчено</translation>
<translation id="370665806235115550">Завантаження...</translation>
<translation id="3712624925041724820">Ліцензії вичерпано</translation>
<translation id="3739623965217189342">Скопійоване посилання</translation>
<translation id="375403751935624634">Не вдалося виконати переклад через помилку сервера.</translation>
<translation id="385051799172605136">Назад</translation>
+<translation id="3858027520442213535">Оновити дату й час</translation>
<translation id="3884278016824448484">Конфліктуючий ідентифікатор пристрою</translation>
<translation id="3885155851504623709">Община</translation>
<translation id="3934680773876859118">Не вдалося завантажити документ PDF</translation>
<translation id="3963721102035795474">Режим перегляду</translation>
<translation id="4030383055268325496">&amp;Відмінити додавання</translation>
-<translation id="4058922952496707368">Ключ &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">ЗАСТЕРЕЖЕННЯ</translation>
+<translation id="4058922952496707368">Ключ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Конфігурацію проксі-сервера налаштовано на використання URL-адреси сценарію .pac, а не фіксованих проксі-серверів.</translation>
<translation id="409504436206021213">Не перезавантажувати</translation>
<translation id="4103249731201008433">Недійсний серійний номер пристрою</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Недійсний підпис</translation>
<translation id="4269787794583293679">(Немає імені користувача)</translation>
<translation id="4300246636397505754">Поради для батьків</translation>
-<translation id="4372948949327679948">Очікуване значення: <ph name="VALUE_TYPE"/>.</translation>
+<translation id="4325863107915753736">Статтю не знайдено</translation>
+<translation id="4372948949327679948">Очікуване значення: <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Ви пробували зв’язатися з доменом <ph name="DOMAIN" />, проте сервер надав сертифікат, відкликаний його видавцем. Це означає, що не варто довіряти обліковим даним системи захисту, наданим сервером. Можливо, ви обмінюєтеся даними зі зловмисником.</translation>
+<translation id="4394049700291259645">Вимкнути</translation>
+<translation id="4424024547088906515">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Chrome не вважає його сертифікат безпеки надійним. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
<translation id="443673843213245140">Використання проксі-сервера вимкнено, але чітко вказано налаштування проксі-сервера.</translation>
-<translation id="4506176782989081258">Помилка перевірки: <ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">Помилка перевірки: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">Видалити адресу з Chrome?</translation>
<translation id="4594403342090139922">&amp;Відмінити видалення</translation>
<translation id="4607653538520819196">Не вдається відкрити цю сторінку через проксі-сервер.</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Його сертифікат безпеки містить помилки. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
<translation id="4726672564094551039">Перезавантажити правила</translation>
+<translation id="4728558894243024398">Платформа</translation>
+<translation id="4771973620359291008">Виникла невідома помилка.</translation>
<translation id="4800132727771399293">Перевірте дату закінчення терміну дії та код CVC та повторіть спробу</translation>
<translation id="4813512666221746211">Помилка мережі</translation>
+<translation id="4816492930507672669">За розміром сторінки</translation>
<translation id="4850886885716139402">Перегляд</translation>
-<translation id="4923417429809017348">Цю сторінку перекладено з невідомої мови оригіналу такою мовою: <ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">Цю сторінку перекладено з невідомої мови оригіналу такою мовою: <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">Потрібно вказати.</translation>
<translation id="4968547170521245791">Не вдається відкрити</translation>
-<translation id="498957508165411911">Перекласти цю мовну пару: <ph name="ORIGINAL_LANGUAGE"/> – <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Перекласти цю мовну пару: <ph name="ORIGINAL_LANGUAGE" /> – <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">Резервний носій пошкоджено</translation>
<translation id="5031870354684148875">Про Перекладач Google</translation>
+<translation id="5045550434625856497">Неправильний пароль</translation>
+<translation id="5087286274860437796">Сертифікат сервера зараз недійсний.</translation>
<translation id="5089810972385038852">Штат</translation>
+<translation id="5094747076828555589">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Chromium не вважає його сертифікат безпеки надійним. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
<translation id="5095208057601539847">Провінція чи область</translation>
<translation id="5145883236150621069">Відповідь правила містить код помилки</translation>
<translation id="5172758083709347301">Комп’ютер</translation>
-<translation id="5179510805599951267">Це не <ph name="ORIGINAL_LANGUAGE"/>? Повідомте про помилку</translation>
+<translation id="5179510805599951267">Це не <ph name="ORIGINAL_LANGUAGE" />? Повідомте про помилку</translation>
<translation id="5190835502935405962">Панель закладок</translation>
+<translation id="5199729219167945352">Експерименти</translation>
+<translation id="5251803541071282808">Хмара</translation>
<translation id="5295309862264981122">Підтвердити перехід</translation>
<translation id="5299298092464848405">Помилка аналізу правила</translation>
+<translation id="5316812925700871227">Обернути проти годинникової стрілки</translation>
<translation id="5317780077021120954">Зберегти</translation>
<translation id="536296301121032821">Помилка збереження налаштувань правила</translation>
-<translation id="5439770059721715174">Помилка перевірки схеми за адресою &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="540969355065856584">Серверу не вдалося підтвердити, що це <ph name="DOMAIN" />. Його сертифікат безпеки зараз недійсний. Можливі причини: неправильна конфігурація або хтось перехопив ваше з’єднання.</translation>
+<translation id="5439770059721715174">Помилка перевірки схеми за адресою "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Недійсна мітка часу правила</translation>
<translation id="5470861586879999274">&amp;Повторити редагування</translation>
<translation id="5509780412636533143">Закладки, якими керує адміністратор</translation>
<translation id="5523118979700054094">Назва правила</translation>
<translation id="552553974213252141">Текст отримано правильно?</translation>
<translation id="5540224163453853">Не вдалося знайти потрібну статтю.</translation>
+<translation id="5556459405103347317">Перезавантажити</translation>
<translation id="5565735124758917034">Активний клієнт</translation>
<translation id="560412284261940334">Керування не підтримується</translation>
<translation id="5629630648637658800">Помилка завантаження налаштувань правила</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Поточний користувач</translation>
<translation id="5813119285467412249">&amp;Повторити додавання</translation>
<translation id="5872918882028971132">Поради для батьків</translation>
-<translation id="587701087903783706">Закрити вікно налаштування для мобільних пристроїв</translation>
<translation id="59107663811261420">Цей продавець не приймає такий тип картки в Google Payments. Виберіть іншу картку.</translation>
+<translation id="5975083100439434680">Зменшити масштаб</translation>
<translation id="5989320800837274978">Не вказано ні фіксованих проксі-серверів, ні URL-адрес сценарію .pac.</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Закрити</translation>
+<translation id="6060685159320643512">Обережно, ці експерименти ненадійні</translation>
+<translation id="6151417162996330722">Сертифікат сервера має задовгий термін дії.</translation>
<translation id="6154808779448689242">Отриманий маркер правила не збігається з поточним маркером</translation>
<translation id="6165508094623778733">Докладніше</translation>
<translation id="6259156558325130047">&amp;Повторити перевпорядкування</translation>
-<translation id="6263376278284652872">Закладки <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Закладки <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Поштовий код</translation>
<translation id="6337534724793800597">Фільтрувати правила за назвою</translation>
+<translation id="6387478394221739770">Хочете спробувати нові цікаві функції Chrome? Завантажте бета-версію зі сторінки chrome.com/beta.</translation>
+<translation id="6426993025560594914">На вашій платформі доступні всі експериментальні функції.</translation>
<translation id="6445051938772793705">Країна</translation>
<translation id="6458467102616083041">Ігнорується, оскільки пошук за умовчанням вимкнено правилом.</translation>
<translation id="647261751007945333">Правила пристрою</translation>
<translation id="6512448926095770873">Залишити цю сторінку</translation>
<translation id="6529602333819889595">&amp;Повторити видалення</translation>
<translation id="6550675742724504774">Параметри</translation>
-<translation id="6597614308054261376">Ви намагаєтеся перейти на сторінку <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Не вдається відкрити цю сторінку через проксі-сервер.</translation>
-<translation id="6628463337424475685">Пошук <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Ви намагаєтеся перейти на сторінку <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Не вдається відкрити цю сторінку через проксі-сервер.</translation>
+<translation id="6628463337424475685">Пошук <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Це правило більше не використовується.</translation>
<translation id="6646897916597483132">Введіть код CVC з 4 цифр, розташований на звороті вашої картки</translation>
+<translation id="674375294223700098">Помилка "Невідомий сертифікат сервера".</translation>
<translation id="6753269504797312559">Значення правила</translation>
<translation id="6831043979455480757">Перекласти</translation>
<translation id="6839929833149231406">Регіон або територія</translation>
<translation id="6874604403660855544">&amp;Повторити додавання</translation>
<translation id="6891596781022320156">Правило не підтримується.</translation>
<translation id="6915804003454593391">Користувач:</translation>
+<translation id="6957887021205513506">Схоже, що сертифікат сервера підроблено.</translation>
<translation id="6965382102122355670">ОК</translation>
<translation id="6965978654500191972">Пристрій</translation>
<translation id="6970216967273061347">Район або округ</translation>
<translation id="6973656660372572881">Указано фіксовані проксі-сервери та URL-адреса сценарію .pac.</translation>
<translation id="6980028882292583085">Сповіщення JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Ви намагалися зв’язатися з доменом <ph name="DOMAIN" />, але сервер надав сертифікат із задовгим терміном дії.</translation>
<translation id="7087282848513945231">Округ або графство</translation>
-<translation id="7108649287766967076">Помилка перекладу такою мовою: <ph name="TARGET_LANGUAGE"/>.</translation>
+<translation id="7108649287766967076">Помилка перекладу такою мовою: <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="7139724024395191329">Емірат</translation>
+<translation id="7179921470347911571">Перезапустити зараз</translation>
<translation id="7180611975245234373">Оновити</translation>
<translation id="7182878459783632708">Правила не встановлено</translation>
-<translation id="7186367841673660872">Цю сторінку перекладено. Мова оригіналу:<ph name="ORIGINAL_LANGUAGE"/>мова перекладу:<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="7186367841673660872">Цю сторінку перекладено. Мова оригіналу:<ph name="ORIGINAL_LANGUAGE" />мова перекладу:<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Пошук у <ph name="SITE_NAME"/> за словами <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Пошук у <ph name="SITE_NAME" /> за словами <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Не вдається встановити конфіденційне з’єднання з <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, оскільки на комп’ютері встановлено неправильні дату й час (<ph name="DATE_AND_TIME" />).</translation>
<translation id="7275334191706090484">Закладки, якими керує адміністратор</translation>
<translation id="7298195798382681320">Рекомендоване</translation>
<translation id="7334320624316649418">&amp;Повторити перевпорядкування</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Обов’язкове</translation>
<translation id="7542995811387359312">Автоматичне заповнення кредитної картки вимкнено, оскільки ця форма не використовує безпечне з'єднання.</translation>
-<translation id="7568593326407688803">Мова цієї сторінки:<ph name="ORIGINAL_LANGUAGE"/>Перекласти її?</translation>
+<translation id="7567204685887185387">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Можливо, його сертифікат безпеки видали шахраї. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
+<translation id="7568593326407688803">Мова цієї сторінки:<ph name="ORIGINAL_LANGUAGE" />Перекласти її?</translation>
<translation id="7569952961197462199">Видалити дані кредитної картки з Chrome?</translation>
-<translation id="7600965453749440009">Ніколи не перекладати з такої мови: <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Значення за межами діапазону <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Сертифікат сервера порушує обмежувальні умови щодо імен.</translation>
+<translation id="7600965453749440009">Ніколи не перекладати з такої мови: <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Значення за межами діапазону <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Хочете спробувати нові цікаві функції Chrome? Завантажте версію для розробників зі сторінки chrome.com/dev.</translation>
<translation id="7752995774971033316">Некерований клієнт</translation>
+<translation id="7761701407923456692">Сертифікат сервера не відповідає URL-адресі.</translation>
<translation id="777702478322588152">Префектура</translation>
<translation id="7791543448312431591">Додати</translation>
<translation id="7805768142964895445">Статус</translation>
<translation id="7813600968533626083">Видалити дані для автозаповнення форм із Chrome?</translation>
<translation id="7887683347370398519">Перевірте код CVC й повторіть спробу</translation>
<translation id="7935318582918952113">Дистилятор DOM</translation>
+<translation id="7938958445268990899">Сертифікат сервера ще не дійсний.</translation>
<translation id="7956713633345437162">Закладки для мобільних пристроїв</translation>
<translation id="7961015016161918242">Ніколи</translation>
<translation id="7977590112176369853">&lt;уведіть запит&gt;</translation>
-<translation id="7983301409776629893">Завжди перекладати цю мовну пару: <ph name="ORIGINAL_LANGUAGE"/> – <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Завжди перекладати цю мовну пару: <ph name="ORIGINAL_LANGUAGE" /> – <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Закладки для настільного комп’ютера</translation>
<translation id="7995512525968007366">Не вказано</translation>
-<translation id="8034522405403831421">Мова цієї сторінки: <ph name="SOURCE_LANGUAGE"/>. Перекласти її такою мовою: <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="8003882219468422867">Обов’язкове корпоративне правило</translation>
+<translation id="8034522405403831421">Мова цієї сторінки: <ph name="SOURCE_LANGUAGE" />. Перекласти її такою мовою: <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8088680233425245692">Не вдалося переглянути статтю.</translation>
<translation id="8091372947890762290">Активація очікує на сервері</translation>
<translation id="8194797478851900357">&amp;Відмінити переміщення</translation>
-<translation id="8201077131113104583">Недійсна URL-адреса для оновлення розширення з ідентифікатором &quot;<ph name="EXTENSION_ID"/>&quot;.</translation>
+<translation id="8201077131113104583">Недійсна URL-адреса для оновлення розширення з ідентифікатором "<ph name="EXTENSION_ID" />".</translation>
<translation id="8208216423136871611">Не зберігати</translation>
<translation id="8218327578424803826">Указане місцезнаходження:</translation>
<translation id="8249320324621329438">Востаннє отримано:</translation>
+<translation id="8294431847097064396">Джерело</translation>
<translation id="8308427013383895095">Переклад не виконано через проблему підключення до мережі.</translation>
<translation id="8311778656528046050">Дійсно перезавантажити цю сторінку?</translation>
<translation id="8349305172487531364">Панель закладок</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Застосовується до:</translation>
<translation id="8530504477309582336">Цей тип картки не підтримується в Google Payments. Виберіть іншу картку.</translation>
<translation id="8553075262323480129">Помилка перекладу. Неможливо визначити мову сторінки.</translation>
-<translation id="8571890674111243710">Виконується переклад сторінки такою мовою: <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Не вдається встановити конфіденційне з’єднання з <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, оскільки на пристрої встановлено неправильні дату й час (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="8571890674111243710">Виконується переклад сторінки такою мовою: <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Скинути все до налаштувань за умовчанням</translation>
<translation id="8713130696108419660">Недійсний початковий підпис</translation>
<translation id="8725066075913043281">Повторити спробу</translation>
+<translation id="8738058698779197622">Щоб установити безпечне з’єднання, потрібно правильно вказати час, оскільки сертифікати, які веб-сайти використовують для самоідентифікації дійсні лише протягом певного періоду часу. Час на вашому пристрої неправильний, тому Chromium не може перевірити сертифікати.</translation>
<translation id="8790007591277257123">&amp;Повторити видалення</translation>
<translation id="8804164990146287819">Політика конфіденційності</translation>
+<translation id="8820817407110198400">Закладки</translation>
<translation id="8824019021993735287">Не вдалося підтвердити дані вашої картки. Спробуйте пізніше.</translation>
-<translation id="8834246243508017242">Увімкнути &quot;Автозаповнення за допомогою контактів&quot;…</translation>
+<translation id="8834246243508017242">Увімкнути "Автозаповнення за допомогою контактів"…</translation>
<translation id="883848425547221593">Інші закладки</translation>
+<translation id="884923133447025588">Не знайдено механізм відкликання.</translation>
<translation id="8866481888320382733">Помилка аналізу налаштувань правила</translation>
<translation id="8876793034577346603">Помилка аналізу конфігурації мережі.</translation>
<translation id="8891727572606052622">Недійсний режим проксі-сервера.</translation>
-<translation id="8940229512486821554">Запустити команду розширення <ph name="EXTENSION_NAME"/>: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">На жаль, цей експеримент не доступний на вашій платформі.</translation>
+<translation id="8903921497873541725">Збільшити масштаб</translation>
+<translation id="8932102934695377596">Ваш годинник запізнюється</translation>
+<translation id="8940229512486821554">Запустити команду розширення <ph name="EXTENSION_NAME" />: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Термін дії сертифіката сервера завершився.</translation>
<translation id="8988760548304185580">Введіть дату закінчення терміну дії та код CVC з 3 цифр, розташований на звороті вашої картки</translation>
-<translation id="9020542370529661692">Цю сторінку перекладено такою мовою: <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Позначки, які застосовуються до всієї системи, може встановлювати лише власник: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Цю сторінку перекладено такою мовою: <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Ви пробували зв’язатися з доменом <ph name="DOMAIN" />, але сервер надав недійсний сертифікат.</translation>
<translation id="9125941078353557812">Введіть код CVC з 3 цифр, розташований на звороті вашої картки</translation>
<translation id="9137013805542155359">Показати оригінал</translation>
<translation id="9148507642005240123">&amp;Відмінити редагування</translation>
<translation id="9154176715500758432">Залишатися на цій сторінці</translation>
<translation id="9170848237812810038">&amp;Скасувати</translation>
+<translation id="917450738466192189">Сертифікат сервера недійсний.</translation>
+<translation id="9187827965378254003">Жоден експеримент наразі не доступний.</translation>
<translation id="9207861905230894330">Не вдалося додати статтю.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">ОЧИСТИТИ ФОРМУ</translation>
+<translation id="988159990683914416">Конструкція розробника</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_vi.xtb b/chromium/components/strings/components_strings_vi.xtb
index 15097814a05..0722066faf9 100644
--- a/chromium/components/strings/components_strings_vi.xtb
+++ b/chromium/components/strings/components_strings_vi.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="vi">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="vi">
+<translation id="1032854598605920125">Xoay theo chiều kim đồng hồ</translation>
<translation id="1055184225775184556">&amp;Hoàn tác thêm</translation>
<translation id="106701514854093668">Dấu trang máy tính</translation>
-<translation id="1103523840287552314">Luôn dịch <ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">Vừa với chiều rộng</translation>
+<translation id="1103523840287552314">Luôn dịch <ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">&amp;Hoàn tác sắp xếp lại</translation>
<translation id="111844081046043029">Bạn có chắc chắn muốn thoát khỏi trang này không?</translation>
<translation id="112840717907525620">Bộ nhớ cache chính sách OK</translation>
<translation id="1132774398110320017">Cài đặt tự động điền trên Chrome...</translation>
-<translation id="1152921474424827756">Truy cập <ph name="BEGIN_LINK"/>bản sao được lưu trong bộ nhớ cache<ph name="END_LINK"/> của <ph name="URL"/></translation>
+<translation id="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="1152921474424827756">Truy cập <ph name="BEGIN_LINK" />bản sao được lưu trong bộ nhớ cache<ph name="END_LINK" /> của <ph name="URL" /></translation>
+<translation id="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="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>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">Tên miền đăng ký:</translation>
<translation id="1344588688991793829">Cài đặt tự động điền trong Chromium...</translation>
<translation id="1426410128494586442">Có</translation>
+<translation id="1430915738399379752">In</translation>
<translation id="1455235771979731432">Đã xảy ra sự cố khi xác minh 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="1491151370853475546">Tải lại trang này</translation>
<translation id="1549470594296187301">Bạn phải bật JavaScript để sử dụng tính năng này.</translation>
-<translation id="1639239467298939599">Đang tải</translation>
<translation id="1640180200866533862">Chính sách người dùng</translation>
<translation id="1644184664548287040">Cấu hình mạng không hợp lệ và không thể nhập được.</translation>
-<translation id="1693754753824026215">Trang trên <ph name="SITE"/> cho biết:</translation>
+<translation id="1655462015569774233">{1,plural, =1{Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này đã hết hạn hôm qua. Điều này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. Đồng hồ máy tính của bạn hiện được đặt là <ph name="CURRENT_DATE" />. Ngày này có đúng không? Nếu không đúng, bạn phải sửa lại đồng hồ của hệ thống rồi làm mới trang này.}other{Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này đã hết hạn cách đây # ngày. Điều này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. Đồng hồ máy tính của bạn hiện được đặt là <ph name="CURRENT_DATE" />. Ngày này có đúng không? Nếu không đúng, bạn phải sửa lại đồng hồ của hệ thống rồi làm mới trang này.}}</translation>
+<translation id="168841957122794586">Chứng chỉ máy chủ chứa khóa mật mã yếu.</translation>
+<translation id="1693754753824026215">Trang trên <ph name="SITE" /> cho biết:</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="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được hệ điều hành thiết bị của bạn tin cậy. Điều này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
<translation id="1821930232296380041">Yêu cầu hoặc tham số yêu cầu không hợp lệ</translation>
-<translation id="1853748787962613237">Không hiển thị được bài viết.</translation>
<translation id="1871208020102129563">Proxy được đặt để sử dụng máy chủ proxy cố định chứ không phải URL tập lệnh .pac.</translation>
-<translation id="1875753206475436906">loại heuristic: <ph name="HEURISTIC_TYPE"/>
- loại máy chủ: <ph name="SERVER_TYPE"/>
- chữ ký trường: <ph name="FIELD_SIGNATURE"/>
- chữ ký biểu mẫu: <ph name="FORM_SIGNATURE"/>
- id thử nghiệm: &quot;<ph name="EXPERIMENT_ID"/>&quot;</translation>
-<translation id="194030505837763158">Truy cập <ph name="LINK"/></translation>
-<translation id="1962204205936693436">Dấu trang của <ph name="DOMAIN"/></translation>
+<translation id="194030505837763158">Truy cập <ph name="LINK" /></translation>
+<translation id="1962204205936693436">Dấu trang của <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Lỗi nối tiếp hóa</translation>
+<translation id="1974060860693918893">Nâng cao</translation>
<translation id="2025186561304664664">Proxy được đặt thành định cấu hình tự động.</translation>
<translation id="2025623846716345241">Xác nhận tải lại</translation>
-<translation id="2030481566774242610">Ý của bạn là <ph name="LINK"/>?</translation>
+<translation id="2030481566774242610">Ý của bạn là <ph name="LINK" />?</translation>
<translation id="2053553514270667976">Mã zip</translation>
<translation id="20817612488360358">Cài đặt proxy hệ thống được đặt để sử dụng nhưng cấu hình proxy rõ ràng cũng được chỉ định.</translation>
<translation id="2094505752054353250">Miền không khớp</translation>
<translation id="2096368010154057602">Khu hành chính</translation>
<translation id="2113977810652731515">Thẻ</translation>
-<translation id="2114841414352855701">Bỏ qua vì đã bị <ph name="POLICY_NAME"/> ghi đè.</translation>
+<translation id="2114841414352855701">Bỏ qua vì đã bị <ph name="POLICY_NAME" /> ghi đè.</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">Dấu trang di động</translation>
+<translation id="2171101176734966184">Bạn đã cố truy cập vào <ph name="DOMAIN" /> nhưng máy chủ xuất trình một chứng chỉ được ký bằng một thuật toán chữ ký yếu. Đ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 có thể đã bị giả mạo và máy chủ đó có thể không phải là máy chủ mà bạn mong đợi (bạn có thể đang giao tiếp với một kẻ tấn công).</translation>
<translation id="2181821976797666341">Chính sách</translation>
<translation id="2212735316055980242">Không tìm thấy chính sách</translation>
<translation id="2213606439339815911">Đang tìm nạp các mục nhập...</translation>
<translation id="225207911366869382">Giá trị này không được dùng cho chính sách này nữa.</translation>
<translation id="2262243747453050782">Lỗi HTTP</translation>
-<translation id="2270192940992995399">Không tìm được bài viết.</translation>
-<translation id="2328300916057834155">Đã bỏ qua dấu trang không hợp lệ tại chỉ mục <ph name="ENTRY_INDEX"/></translation>
+<translation id="2282872951544483773">Thử nghiệm không khả dụng</translation>
+<translation id="229702904922032456">Chứng chỉ sơ cấp hoặc trung cấp đã hết hạn.</translation>
+<translation id="2328300916057834155">Đã bỏ qua dấu trang không hợp lệ tại chỉ mục <ph name="ENTRY_INDEX" /></translation>
<translation id="2354001756790975382">Dấu trang khác</translation>
<translation id="2359808026110333948">Tiếp tục</translation>
<translation id="2367567093518048410">Mức độ</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="2396249848217231973">&amp;Hoàn tác xóa</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="2455981314101692989">Trang web này đã vô hiệu hóa tính năng tự động điền cho biểu mẫu này.</translation>
<translation id="2479410451996844060">URL tìm kiếm hợp lệ.</translation>
+<translation id="2491120439723279231">Chứng chỉ của máy chủ có lỗi.</translation>
<translation id="2495083838625180221">Trình phân tích cú pháp JSON</translation>
<translation id="2498091847651709837">Quét thẻ mới</translation>
<translation id="2556876185419854533">&amp;Hoàn tác chỉnh sửa</translation>
-<translation id="2581221116934462656">Bạn có muốn <ph name="PRODUCT_NAME"/> đưa ra đề nghị dịch các trang <ph name="LANGUAGE_NAME"/> từ trang web này vào lần sau không?</translation>
+<translation id="2581221116934462656">Bạn có muốn <ph name="PRODUCT_NAME" /> đưa ra đề nghị dịch các trang <ph name="LANGUAGE_NAME" /> từ trang web này vào lần sau không?</translation>
<translation id="2587841377698384444">ID API thư mục:</translation>
<translation id="2597378329261239068">Tài liệu này được bảo vệ bằng mật khẩu. Vui lòng nhập mật khẩu.</translation>
+<translation id="2625385379895617796">Đồng hồ của bạn chạy nhanh</translation>
<translation id="2639739919103226564">Trạng thái:</translation>
+<translation id="2653659639078652383">Gửi</translation>
<translation id="2704283930420550640">Giá trị không khớp với định dạng.</translation>
<translation id="2721148159707890343">Yêu cầu đã thành công</translation>
+<translation id="2728127805433021124">Chứng chỉ của máy chủ đã được ký bằng thuật toán chữ ký yếu.</translation>
<translation id="2774256287122201187">Bạn có thể tiếp tục. Nếu bạn tiếp tục đến trang, cảnh báo này sẽ không xuất hiện lại sau năm phút.</translation>
<translation id="277499241957683684">Thiếu hồ sơ thiết bị</translation>
<translation id="2835170189407361413">Xóa biểu mẫu</translation>
-<translation id="2855922900409897335">Xác minh <ph name="CREDIT_CARD"/> của bạn</translation>
+<translation id="2855922900409897335">Xác minh <ph name="CREDIT_CARD" /> của bạn</translation>
+<translation id="2915500479781995473">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này đã hết hạn. Đ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. Đồng hồ trên máy tính của bạn hiện được đặt là <ph name="CURRENT_TIME" />. Giờ này có đúng không? Nếu không đúng, bạn phải sửa lại giờ hệ thống rồi làm mới trang này.</translation>
+<translation id="2922350208395188000">Không thể kiểm tra chứng chỉ của máy chủ.</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="2958431318199492670">Cấu hình mạng không tuân thủ tiêu chuẩn ONC. Các bộ phận của cấu hình có thể không được nhập.</translation>
<translation id="2972581237482394796">&amp;Làm lại</translation>
-<translation id="3010559122411665027">Mục nhập danh sách &quot;<ph name="ENTRY_INDEX"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="3010559122411665027">Mục nhập danh sách "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
<translation id="3024663005179499861">Loại chính sách sai</translation>
<translation id="3105172416063519923">ID phần tử:</translation>
<translation id="3145945101586104090">Không thể giải mã phản hồi</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Khám phá</translation>
<translation id="3174168572213147020">Đảo</translation>
<translation id="3219579145727097045">Nhập ngày hết hạn và CVC gồm 4 chữ số ở mặt trước thẻ của bạn</translation>
-<translation id="3228969707346345236">Dịch thất bại vì trang đã bằng <ph name="LANGUAGE"/>.</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="3228969707346345236">Dịch thất bại vì trang đã bằng <ph name="LANGUAGE" />.</translation>
<translation id="3270847123878663523">&amp;Hoàn tác sắp xếp lại</translation>
+<translation id="3286538390144397061">Khởi động lại Ngay bây giờ</translation>
<translation id="333371639341676808">Ngăn không cho trang này tạo hộp thoại bổ sung.</translation>
-<translation id="3369366829301677151">Cập nhật và xác minh <ph name="CREDIT_CARD"/> của bạn</translation>
+<translation id="3340978935015468852">cài đặt</translation>
+<translation id="3369192424181595722">Lỗi đồng hồ</translation>
+<translation id="3369366829301677151">Cập nhật và xác minh <ph name="CREDIT_CARD" /> của bạn</translation>
<translation id="337363190475750230">Đã hủy cấp phép</translation>
<translation id="3377188786107721145">Lỗi phân tích cú pháp chính sách</translation>
<translation id="3380365263193509176">Lỗi không xác định</translation>
<translation id="3380864720620200369">ID ứng dụng khách:</translation>
<translation id="3427342743765426898">&amp;Làm lại chỉnh sửa</translation>
+<translation id="3435896845095436175">Bật</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Khoảng thời gian tìm nạp:</translation>
+<translation id="3462200631372590220">Ẩn chi tiết</translation>
+<translation id="3528171143076753409">Chứng chỉ của máy chủ không đáng tin cậy.</translation>
<translation id="3542684924769048008">Sử dụng mật khẩu cho:</translation>
<translation id="3583757800736429874">&amp;Làm lại di chuyển</translation>
<translation id="3623476034248543066">Hiển thị giá trị</translation>
+<translation id="3648607100222897006">Các tính năng thử nghiệm này có thể thay đổi, hỏng hoặc biến mất bất kỳ lúc nào. Chúng tôi hoàn toàn không đảm bảo về những điều có thể xảy ra nếu bạn bật một trong các thử nghiệm này và trình duyệt của bạn thậm chí có thể tự động biến mất. Ngoài những điều đã nói, trình duyệt của bạn có thể xóa tất cả dữ liệu của bạn hoặc tính bảo mật và sự riêng tư của bạn có thể bị xâm phạm theo cách không mong đợi. Bất kỳ tính năng thử nghiệm nào mà bạn bật sẽ được bật cho tất cả người dùng của trình duyệt này. Hãy tiến hành một cách thận trọng.</translation>
<translation id="3650584904733503804">Xác thực thành công</translation>
<translation id="370665806235115550">Đang tải...</translation>
<translation id="3712624925041724820">Giấy phép không đủ</translation>
<translation id="3739623965217189342">Liên kết đã sao chép</translation>
<translation id="375403751935624634">Không thể dịch do lỗi máy chủ.</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>
<translation id="3885155851504623709">Xã</translation>
<translation id="3934680773876859118">Không thể tải tài liệu PDF</translation>
<translation id="3963721102035795474">Chế độ đọc</translation>
<translation id="4030383055268325496">&amp;Hoàn tác thêm</translation>
-<translation id="4058922952496707368">Khóa &quot;<ph name="SUBKEY"/>&quot;: <ph name="ERROR"/></translation>
+<translation id="404928562651467259">CẢNH BÁO</translation>
+<translation id="4058922952496707368">Khóa "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
<translation id="4079302484614802869">Cấu hình proxy được đặt để sử dụng URL tập lệnh .pac chứ không phải máy chủ proxy cố định.</translation>
<translation id="409504436206021213">Không tải lại</translation>
<translation id="4103249731201008433">Số sê-ri thiết bị không hợp lệ</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">Chữ ký không hợp lệ</translation>
<translation id="4269787794583293679">(Không có tên người dùng)</translation>
<translation id="4300246636397505754">Đề xuất chính</translation>
-<translation id="4372948949327679948">Giá trị <ph name="VALUE_TYPE"/> mong đợi.</translation>
+<translation id="4325863107915753736">Không tìm được bài viết</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="4394049700291259645">Vô hiệu hóa</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="443673843213245140">Đã tắt sử dụng proxy nhưng cấu hình proxy rõ ràng được chỉ định.</translation>
-<translation id="4506176782989081258">Lỗi xác thực: <ph name="VALIDATION_ERROR"/>.</translation>
+<translation id="4506176782989081258">Lỗi xác thực: <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4587425331216688090">Xóa địa chỉ khỏi Chrome?</translation>
<translation id="4594403342090139922">&amp;Hoàn tác xóa</translation>
<translation id="4607653538520819196">Trình tiết kiệm dữ liệu không thể ủy quyền trang này.</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="4726672564094551039">Tải lại chính sách</translation>
+<translation id="4728558894243024398">Nền tảng</translation>
+<translation id="4771973620359291008">Xảy ra lỗi chưa biết.</translation>
<translation id="4800132727771399293">Kiểm tra ngày hết hạn và CVC của bạn rồi thử lại</translation>
<translation id="4813512666221746211">Lỗi mạng</translation>
+<translation id="4816492930507672669">Vừa với trang</translation>
<translation id="4850886885716139402">Xem</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="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="4926049483395192435">Phải được chỉ định.</translation>
<translation id="4968547170521245791">Không thể ủy quyền</translation>
-<translation id="498957508165411911">Dịch từ <ph name="ORIGINAL_LANGUAGE"/> sang <ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">Dịch từ <ph name="ORIGINAL_LANGUAGE" /> sang <ph name="TARGET_LANGUAGE" />?</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="5031870354684148875">Giới thiệu về Google Dịch</translation>
+<translation id="5045550434625856497">Mật khẩu sai</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="5089810972385038852">Tiểu bang</translation>
+<translation id="5094747076828555589">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được Chromium tin cậy. Điều này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
<translation id="5095208057601539847">Tỉnh/thành phố</translation>
<translation id="5145883236150621069">Mã lỗi có trong phản hồi chính sách</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="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="5199729219167945352">Thử nghiệm</translation>
+<translation id="5251803541071282808">Đám mây</translation>
<translation id="5295309862264981122">Xác nhận Điều hướng</translation>
<translation id="5299298092464848405">Lỗi phân tích cú pháp chính sách</translation>
+<translation id="5316812925700871227">Xoay ngược chiều kim đồng hồ</translation>
<translation id="5317780077021120954">Lưu</translation>
<translation id="536296301121032821">Không thể lưu trữ cài đặt chính sách</translation>
-<translation id="5439770059721715174">Lỗi xác thực lược đồ tại &quot;<ph name="ERROR_PATH"/>&quot;: <ph name="ERROR"/></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="5439770059721715174">Lỗi xác thực lược đồ tại "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5455374756549232013">Dấu thời gian chính sách không hợp lệ</translation>
<translation id="5470861586879999274">&amp;Làm lại chỉnh sửa</translation>
<translation id="5509780412636533143">Dấu trang được quản lý</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="5540224163453853">Không thể tìm thấy bài viết đã yêu cầu.</translation>
+<translation id="5556459405103347317">Tải lại</translation>
<translation id="5565735124758917034">Đang hoạt động</translation>
<translation id="560412284261940334">Không hỗ trợ quản lý</translation>
<translation id="5629630648637658800">Không thể tải cài đặt chính sách</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">Người dùng hiện tại</translation>
<translation id="5813119285467412249">&amp;Làm lại thêm</translation>
<translation id="5872918882028971132">Đề xuất chính</translation>
-<translation id="587701087903783706">Đóng chế độ xem thân thiện với thiết bị di động</translation>
<translation id="59107663811261420">Loại thẻ này không được Google Payments hỗ trợ cho người bán này. Vui lòng chọn thẻ khác.</translation>
+<translation id="5975083100439434680">Thu nhỏ</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="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">Đóng</translation>
+<translation id="6060685159320643512">Hãy cẩn thận, thử nghiệm này có thể gây lỗi</translation>
+<translation id="6151417162996330722">Chứng chỉ máy chủ có thời gian hiệu lực quá dài.</translation>
<translation id="6154808779448689242">Mã thông báo chính sách trả lại không phù hợp với mã thông báo hiện tại</translation>
<translation id="6165508094623778733">Tìm hiểu thêm</translation>
<translation id="6259156558325130047">&amp;Làm lại sắp xếp lại</translation>
-<translation id="6263376278284652872">Dấu trang trên <ph name="DOMAIN"/></translation>
+<translation id="6263376278284652872">Dấu trang trên <ph name="DOMAIN" /></translation>
<translation id="6282194474023008486">Mã bưu chính</translation>
<translation id="6337534724793800597">Lọc chính sách theo tên</translation>
+<translation id="6387478394221739770">Bạn quan tâm đến các tính năng mới thú vị của Chrome? Hãy dùng thử kênh thử nghiệm beta của chúng tôi tại chrome.com/beta.</translation>
+<translation id="6426993025560594914">Tất cả các thử nghiệm đều khả dụng trên nền tảng của bạn!</translation>
<translation id="6445051938772793705">Quốc gia</translation>
<translation id="6458467102616083041">Bị bỏ qua vì chính sách đã tắt tìm kiếm mặc định.</translation>
<translation id="647261751007945333">Chính sách thiết bị</translation>
<translation id="6512448926095770873">Rời khỏi Trang này</translation>
<translation id="6529602333819889595">&amp;Làm lại xóa</translation>
<translation id="6550675742724504774">Tùy chọn</translation>
-<translation id="6597614308054261376">Bạn đang cố gắng truy cập vào <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>. Trình tiết kiệm dữ liệu không thể ủy quyền trang này tại thời điểm này.</translation>
-<translation id="6628463337424475685">Tìm kiếm trên <ph name="ENGINE"/></translation>
+<translation id="6597614308054261376">Bạn đang cố gắng truy cập vào <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Trình tiết kiệm dữ liệu không thể ủy quyền trang này tại thời điểm này.</translation>
+<translation id="6628463337424475685">Tìm kiếm trên <ph name="ENGINE" /></translation>
<translation id="6644283850729428850">Chính sách này không được chấp thuận.</translation>
<translation id="6646897916597483132">Nhập CVC gồm 4 chữ số ở mặt trước thẻ của bạn</translation>
+<translation id="674375294223700098">Lỗi chứng chỉ máy chủ không xác định.</translation>
<translation id="6753269504797312559">Giá trị chính sách</translation>
<translation id="6831043979455480757">Dịch</translation>
<translation id="6839929833149231406">Khu vực</translation>
<translation id="6874604403660855544">&amp;Làm lại thêm</translation>
<translation id="6891596781022320156">Cấp chính sách không được hỗ trợ.</translation>
<translation id="6915804003454593391">Người dùng:</translation>
+<translation id="6957887021205513506">Chứng chỉ của máy chủ dường như giả mạo.</translation>
<translation id="6965382102122355670">OK</translation>
<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="6980028882292583085">Cảnh báo JavaScript</translation>
<translation id="7012363358306927923">China UnionPay</translation>
+<translation id="7050187094878475250">Bạn đã cố gắng truy cập <ph name="DOMAIN" /> nhưng máy chủ đã hiển thị chứng chỉ có thời gian hiệu lực quá dài để có thể tin cậy.</translation>
<translation id="7087282848513945231">Hạt</translation>
-<translation id="7108649287766967076">Bản dịch sang <ph name="TARGET_LANGUAGE"/> không thành công.</translation>
+<translation id="7108649287766967076">Bản dịch sang <ph name="TARGET_LANGUAGE" /> không thành công.</translation>
<translation id="7139724024395191329">Tiểu vương quốc</translation>
+<translation id="7179921470347911571">Chạy lại ngay bây giờ</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="7186367841673660872">Trang này đã được dịch từ<ph name="ORIGINAL_LANGUAGE" />sang<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">Tìm kiếm <ph name="SITE_NAME"/> cho <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">Tìm kiếm <ph name="SITE_NAME" /> cho <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">Không thể thiết lập kết nối riêng tư với <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> vì ngày và giờ (<ph name="DATE_AND_TIME" />) trên máy tính của bạn không đúng.</translation>
<translation id="7275334191706090484">Dấu trang được quản lý</translation>
<translation id="7298195798382681320">Được đề xuất</translation>
<translation id="7334320624316649418">&amp;Làm lại sắp xếp lại</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">Bắt buộc</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="7568593326407688803">Trang này bằng<ph name="ORIGINAL_LANGUAGE"/>Bạn có muốn dịch trang này không?</translation>
+<translation id="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="7568593326407688803">Trang này bằng<ph name="ORIGINAL_LANGUAGE" />Bạn có muốn dịch trang này không?</translation>
<translation id="7569952961197462199">Xóa thẻ tín dụng khỏi Chrome?</translation>
-<translation id="7600965453749440009">Không bao giờ dịch <ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">Giá trị nằm ngoài phạm vi <ph name="VALUE"/>.</translation>
+<translation id="7592362899630581445">Chứng chỉ của máy chủ vi phạm hạn chế tên.</translation>
+<translation id="7600965453749440009">Không bao giờ dịch <ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">Giá trị nằm ngoài phạm vi <ph name="VALUE" />.</translation>
+<translation id="7674629440242451245">Bạn quan tâm đến các tính năng mới thú vị của Chrome? Hãy dùng thử kênh nhà phát triển của chúng tôi tại chrome.com/dev.</translation>
<translation id="7752995774971033316">Không được quản lý</translation>
+<translation id="7761701407923456692">Chứng chỉ của máy chủ không phù hợp với URL.</translation>
<translation id="777702478322588152">Quận</translation>
<translation id="7791543448312431591">Thêm</translation>
<translation id="7805768142964895445">Trạng thái</translation>
<translation id="7813600968533626083">Xóa đề xuất biểu mẫu khỏi Chrome?</translation>
<translation id="7887683347370398519">Kiểm tra CVC của bạn và thử lại</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">Chứng chỉ của máy chủ chưa hợp lệ.</translation>
<translation id="7956713633345437162">Dấu trang di động</translation>
<translation id="7961015016161918242">Chưa bao giờ</translation>
<translation id="7977590112176369853">&lt;nhập truy vấn&gt;</translation>
-<translation id="7983301409776629893">Luôn dịch <ph name="ORIGINAL_LANGUAGE"/> sang <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">Luôn dịch <ph name="ORIGINAL_LANGUAGE" /> sang <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">Dấu trang máy tính</translation>
<translation id="7995512525968007366">Không chỉ định</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="8003882219468422867">Ghi đè trong môi trường doanh nghiệp</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="8088680233425245692">Không xem được bài viết.</translation>
<translation id="8091372947890762290">Kích hoạt đang chờ xử lý trên máy chủ</translation>
<translation id="8194797478851900357">&amp;Hoàn tác di chuyển</translation>
-<translation id="8201077131113104583">URL cập nhật không hợp lệ cho tiện ích có ID &quot;<ph name="EXTENSION_ID"/>&quot;.</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="8208216423136871611">Không lưu</translation>
<translation id="8218327578424803826">Vị trí được gán:</translation>
<translation id="8249320324621329438">Tìm nạp lần cuối:</translation>
+<translation id="8294431847097064396">Nguồn</translation>
<translation id="8308427013383895095">Không thể dịch do kết nối mạng có sự cố.</translation>
<translation id="8311778656528046050">Bạn có chắc chắn muốn tải lại trang này không?</translation>
<translation id="8349305172487531364">Thanh dấu trang</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">Áp dụng cho</translation>
<translation id="8530504477309582336">Google Payments không hỗ trợ loại thẻ này. Vui lòng chọn thẻ khác.</translation>
<translation id="8553075262323480129">Dịch thất bại do ngôn ngữ của trang không được xác định.</translation>
-<translation id="8571890674111243710">Đang dịch trang sang <ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">Không thể thiết lập kết nối riêng tư với <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> vì ngày và giờ (<ph name="DATE_AND_TIME" />) trên thiết bị của bạn không đúng.</translation>
+<translation id="8571890674111243710">Đang dịch trang sang <ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">Đặt lại tất cả về mặc định</translation>
<translation id="8713130696108419660">Chữ ký ban đầu không hợp lệ</translation>
<translation id="8725066075913043281">Thử lại</translation>
+<translation id="8738058698779197622">Để thiết lập kết nối an toàn, bạn cần đặt thời gian đúng cho đồng hồ. Nguyên nhân là do chứng chỉ mà các trang web dùng để tự nhận dạng chỉ có hiệu lực trong khoảng thời gian cụ thể. Vì đồng hồ trên thiết bị của bạn không đúng nên Chromium không thể xác minh các chứng chỉ này.</translation>
<translation id="8790007591277257123">&amp;Làm lại xóa</translation>
<translation id="8804164990146287819">Chính sách bảo mật</translation>
+<translation id="8820817407110198400">Dấu trang</translation>
<translation id="8824019021993735287">Chrome không thể xác minh thẻ của bạn vào lúc này. Vui lòng thử lại sau.</translation>
<translation id="8834246243508017242">Bật Tự động điền bằng Liên hệ…</translation>
<translation id="883848425547221593">Dấu trang Khác</translation>
+<translation id="884923133447025588">Không tìm thấy cơ chế thu hồi.</translation>
<translation id="8866481888320382733">Lỗi phân tích cú pháp cài đặt chính sách</translation>
<translation id="8876793034577346603">Không thể phân tích cú pháp cấu hình mạng.</translation>
<translation id="8891727572606052622">Chế độ proxy không hợp lệ.</translation>
-<translation id="8940229512486821554">Chạy <ph name="EXTENSION_NAME"/> lệnh: <ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">Rất tiếc, thử nghiệm này không sẵn có trên nền tảng của bạn.</translation>
+<translation id="8903921497873541725">Phóng to</translation>
+<translation id="8932102934695377596">Đồng hồ của bạn chạy chậm</translation>
+<translation id="8940229512486821554">Chạy <ph name="EXTENSION_NAME" /> lệnh: <ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">Chứng chỉ của máy chủ đã hết hạn.</translation>
<translation id="8988760548304185580">Nhập ngày hết hạn và CVC gồm 3 chữ số ở mặt sau thẻ của bạn</translation>
-<translation id="9020542370529661692">Trang này đã được dịch sang <ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">Chỉ chủ sở hữu mới có thể đặt cờ áp dụng cho toàn hệ thống: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020542370529661692">Trang này đã được dịch sang <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">Bạn đã cố truy cập vào <ph name="DOMAIN" />, nhưng máy chủ cho biết chứng chỉ không hợp lệ.</translation>
<translation id="9125941078353557812">Nhập CVC gồm 3 chữ số ở mặt sau thẻ của bạn</translation>
<translation id="9137013805542155359">Hiển thị văn bản gốc</translation>
<translation id="9148507642005240123">&amp;Hoàn tác chỉnh sửa</translation>
<translation id="9154176715500758432">Ở lại Trang này</translation>
<translation id="9170848237812810038">H&amp;oàn tác</translation>
+<translation id="917450738466192189">Chứng chỉ của máy chủ không hợp lệ.</translation>
+<translation id="9187827965378254003">Rất tiếc, có vẻ như hiện không có thử nghiệm nào sẵn có.</translation>
<translation id="9207861905230894330">Không thêm được bài viết.</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">XÓA BIỂU MẪU</translation>
+<translation id="988159990683914416">Phiên bản dành cho Nhà phát triển</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_zh-CN.xtb b/chromium/components/strings/components_strings_zh-CN.xtb
index 3dc6cc1c607..f6f66464bd9 100644
--- a/chromium/components/strings/components_strings_zh-CN.xtb
+++ b/chromium/components/strings/components_strings_zh-CN.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="zh-CN">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="zh-CN">
+<translation id="1032854598605920125">顺时针旋转</translation>
<translation id="1055184225775184556">撤消添加(&amp;U)</translation>
<translation id="106701514854093668">桌面书签</translation>
-<translation id="1103523840287552314">总是翻译<ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">适合窗口宽度</translation>
+<translation id="1103523840287552314">总是翻译<ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">撤消顺序调整(&amp;U)</translation>
<translation id="111844081046043029">确定要离开此页吗?</translation>
<translation id="112840717907525620">策略缓存良好</translation>
<translation id="1132774398110320017">Chrome自动填充设置…</translation>
-<translation id="1152921474424827756">访问<ph name="URL"/>的<ph name="BEGIN_LINK"/>缓存副本<ph name="END_LINK"/></translation>
+<translation id="1150979032973867961">此服务器无法证明它是<ph name="DOMAIN" />;您计算机的操作系统不信任其安全证书。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
+<translation id="1152921474424827756">访问<ph name="URL" />的<ph name="BEGIN_LINK" />缓存副本<ph name="END_LINK" /></translation>
+<translation id="121201262018556460">您尝试访问的是 <ph name="DOMAIN" />,但是服务器出示的证书包含弱密钥。攻击者可能已经破解了私钥,因此这可能并不是您想要访问的服务器(您可能正在与攻击者进行通信)。</translation>
<translation id="1227224963052638717">未知政策。</translation>
<translation id="1227633850867390598">隐藏值</translation>
<translation id="1228893227497259893">实体标识符有误</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">注册域:</translation>
<translation id="1344588688991793829">Chromium自动填充设置…</translation>
<translation id="1426410128494586442">是</translation>
+<translation id="1430915738399379752">打印</translation>
<translation id="1455235771979731432">验证您的信用卡时出现问题。请检查您的互联网连接,然后重试。</translation>
<translation id="1491151370853475546">重新加载此页</translation>
<translation id="1549470594296187301">必须启用 JavaScript 才能使用此功能。</translation>
-<translation id="1639239467298939599">正在加载</translation>
<translation id="1640180200866533862">用户政策</translation>
<translation id="1644184664548287040">网络配置无效,无法导入。</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> 上的网页显示:</translation>
+<translation id="1655462015569774233">{1,plural, =1{此服务器无法证明它是 <ph name="DOMAIN" />;其安全证书已在昨天过期。出现此问题的原因可能是配置有误,或有攻击者拦截了您的连接。计算机的时钟目前已设为 <ph name="CURRENT_DATE" />,该设置是否正确?如果不正确,请更正系统的时钟,然后刷新此页面。}other{此服务器无法证明它是 <ph name="DOMAIN" />;其安全证书已在 # 天前过期。出现此问题的原因可能是配置有误,或有攻击者拦截了您的连接。计算机的时钟目前已设为 <ph name="CURRENT_DATE" />,该设置是否正确?如果不正确,请更正系统的时钟,然后刷新此页面。}}</translation>
+<translation id="168841957122794586">服务器证书包含弱加密密钥。</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> 上的网页显示:</translation>
+<translation id="1706954506755087368">{1,plural, =1{此服务器无法证明它是 <ph name="DOMAIN" />;其安全证书明天才会生效。出现此问题的原因可能是配置有误,或有攻击者拦截了您的连接。}other{此服务器无法证明它是 <ph name="DOMAIN" />;其安全证书 # 天后才会生效。出现此问题的原因可能是配置有误,或有攻击者拦截了您的连接。}}</translation>
<translation id="1734864079702812349">美国运通卡</translation>
+<translation id="1763864636252898013">此服务器无法证明它是<ph name="DOMAIN" />;您设备的操作系统不信任其安全证书。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
<translation id="1821930232296380041">请求或请求参数无效</translation>
-<translation id="1853748787962613237">无法显示文章。</translation>
<translation id="1871208020102129563">代理已设置为使用固定的代理服务器,而不是 .pac 脚本网址。</translation>
-<translation id="1875753206475436906">试探法类型:<ph name="HEURISTIC_TYPE"/>
- 服务器类型:<ph name="SERVER_TYPE"/>
- 字段签名:<ph name="FIELD_SIGNATURE"/>
- 表单签名:<ph name="FORM_SIGNATURE"/>
- 实验ID:<ph name="EXPERIMENT_ID"/></translation>
-<translation id="194030505837763158">请访问<ph name="LINK"/></translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/>书签</translation>
+<translation id="194030505837763158">请访问<ph name="LINK" /></translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" />书签</translation>
<translation id="1973335181906896915">序列化错误</translation>
+<translation id="1974060860693918893">高级</translation>
<translation id="2025186561304664664">代理已设为自动配置。</translation>
<translation id="2025623846716345241">确认重新加载</translation>
-<translation id="2030481566774242610">您是想访问<ph name="LINK"/>吗?</translation>
+<translation id="2030481566774242610">您是想访问<ph name="LINK" />吗?</translation>
<translation id="2053553514270667976">邮编</translation>
<translation id="20817612488360358">已设置为使用系统代理设置,但同时指定了一个明确的代理配置。</translation>
<translation id="2094505752054353250">网域不匹配</translation>
<translation id="2096368010154057602">省</translation>
<translation id="2113977810652731515">信用卡</translation>
-<translation id="2114841414352855701">由于已被 <ph name="POLICY_NAME"/> 替换,该政策已忽略。</translation>
+<translation id="2114841414352855701">由于已被 <ph name="POLICY_NAME" /> 替换,该政策已忽略。</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">移动设备书签</translation>
+<translation id="2171101176734966184">您尝试访问的是 <ph name="DOMAIN" />,但是服务器出示的证书是使用弱签名算法签署的。这意味着服务器出示的安全凭据可能是伪造的,因此这可能并不是您想要访问的服务器(您可能正在与攻击者进行通信)。</translation>
<translation id="2181821976797666341">政策</translation>
<translation id="2212735316055980242">找不到策略</translation>
<translation id="2213606439339815911">正在获取条目…</translation>
<translation id="225207911366869382">适用于该政策的此值已弃用。</translation>
<translation id="2262243747453050782">HTTP 错误</translation>
-<translation id="2270192940992995399">找不到文章。</translation>
-<translation id="2328300916057834155">已忽略索引<ph name="ENTRY_INDEX"/>中的无效书签</translation>
+<translation id="2282872951544483773">无法使用的实验功能</translation>
+<translation id="229702904922032456">根证书或中间证书已过期。</translation>
+<translation id="2328300916057834155">已忽略索引<ph name="ENTRY_INDEX" />中的无效书签</translation>
<translation id="2354001756790975382">其他书签</translation>
<translation id="2359808026110333948">继续</translation>
<translation id="2367567093518048410">级别</translation>
+<translation id="2384307209577226199">在企业环境中默认实施</translation>
+<translation id="2386255080630008482">服务器的证书已撤消。</translation>
<translation id="2392959068659972793">显示未设定值的政策</translation>
<translation id="2396249848217231973">撤消删除(&amp;U)</translation>
+<translation id="2413528052993050574">此服务器无法证明它是<ph name="DOMAIN" />;其安全证书可能已被撤消。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
<translation id="2455981314101692989">该网页已对该表单停用自动填充功能。</translation>
<translation id="2479410451996844060">搜索网址无效。</translation>
+<translation id="2491120439723279231">服务器证书中包含错误。</translation>
<translation id="2495083838625180221">JSON 解析器</translation>
<translation id="2498091847651709837">扫描新的信用卡</translation>
<translation id="2556876185419854533">撤消修改(&amp;U)</translation>
-<translation id="2581221116934462656">您希望 <ph name="PRODUCT_NAME"/> 下次翻译此网站的<ph name="LANGUAGE_NAME"/>网页吗?</translation>
+<translation id="2581221116934462656">您希望 <ph name="PRODUCT_NAME" /> 下次翻译此网站的<ph name="LANGUAGE_NAME" />网页吗?</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">本文档设置了密码保护,请输入密码。</translation>
+<translation id="2625385379895617796">您的时钟快了</translation>
<translation id="2639739919103226564">状态:</translation>
+<translation id="2653659639078652383">提交</translation>
<translation id="2704283930420550640">值不符合格式要求。</translation>
<translation id="2721148159707890343">请求成功</translation>
+<translation id="2728127805433021124">服务器的证书是使用弱签名算法进行签名的。</translation>
<translation id="2774256287122201187">您可以继续。如果您继续前往该页面,那么在接下来的 5 分钟内将不会再看到此警告。</translation>
<translation id="277499241957683684">缺少设备记录</translation>
<translation id="2835170189407361413">清除表单</translation>
-<translation id="2855922900409897335">验证您的 <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">验证您的 <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">此服务器无法证明它是<ph name="DOMAIN" />;其安全证书已过期。出现此问题的原因可能是配置有误或您的连接被拦截了。计算机的时钟目前已设为<ph name="CURRENT_TIME" />,该设置是否正确?如果不正确,请更正系统的时钟,然后刷新此页面。</translation>
+<translation id="2922350208395188000">无法核实服务器证书。</translation>
+<translation id="2941952326391522266">此服务器无法证明它是<ph name="DOMAIN" />;其安全证书来自<ph name="DOMAIN2" />。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
<translation id="2958431318199492670">网络配置不符合 ONC 标准。无法导入配置的某些部分。</translation>
<translation id="2972581237482394796">重做(&amp;R)</translation>
-<translation id="3010559122411665027">列表条目“<ph name="ENTRY_INDEX"/>”:<ph name="ERROR"/></translation>
+<translation id="3010559122411665027">列表条目“<ph name="ENTRY_INDEX" />”:<ph name="ERROR" /></translation>
<translation id="3024663005179499861">策略类型有误</translation>
<translation id="3105172416063519923">资产 ID:</translation>
<translation id="3145945101586104090">无法对响应解码</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">岛</translation>
<translation id="3219579145727097045">输入信用卡正面显示的到期日期和 4 位数银行卡验证码 (CVC)</translation>
-<translation id="3228969707346345236">此网页已经是<ph name="LANGUAGE"/>网页,因此无法翻译。</translation>
+<translation id="3225919329040284222">服务器提供的证书与内置预期证书不匹配。这些预期证书是针对某些高安全性网站提供的,以便为您提供保护。</translation>
+<translation id="3228969707346345236">此网页已经是<ph name="LANGUAGE" />网页,因此无法翻译。</translation>
<translation id="3270847123878663523">撤消顺序调整(&amp;U)</translation>
+<translation id="3286538390144397061">立即重新启动</translation>
<translation id="333371639341676808">禁止此页再显示对话框。</translation>
-<translation id="3369366829301677151">更新并验证您的 <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">设置</translation>
+<translation id="3369192424181595722">时钟错误</translation>
+<translation id="3369366829301677151">更新并验证您的 <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">已取消配置</translation>
<translation id="3377188786107721145">策略解析错误</translation>
<translation id="3380365263193509176">未知错误</translation>
<translation id="3380864720620200369">客户端 ID:</translation>
<translation id="3427342743765426898">恢复修改(&amp;R)</translation>
+<translation id="3435896845095436175">启用</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">抓取时间间隔:</translation>
+<translation id="3462200631372590220">隐藏详情</translation>
+<translation id="3528171143076753409">服务器的证书不受信任。</translation>
<translation id="3542684924769048008">使用以下项的密码:</translation>
<translation id="3583757800736429874">恢复移动(&amp;R)</translation>
<translation id="3623476034248543066">显示值</translation>
+<translation id="3648607100222897006">这些实验性功能随时可能会更改、中止或取消。因此,我们完全无法保证您启用某项实验性功能后会发生什么情况,您的浏览器甚至可能会自动崩溃。请注意,您的浏览器可能会删除您的所有数据,您的安全和隐私也有可能受到意外伤害。您启用的所有实验性功能将用于此浏览器的所有用户。启用前,请务必三思。</translation>
<translation id="3650584904733503804">验证成功</translation>
<translation id="370665806235115550">正在加载...</translation>
<translation id="3712624925041724820">许可已用尽</translation>
<translation id="3739623965217189342">您复制的链接</translation>
<translation id="375403751935624634">由于服务器出错,翻译失败。</translation>
<translation id="385051799172605136">后退</translation>
+<translation id="3858027520442213535">更新日期和时间</translation>
<translation id="3884278016824448484">设备标识符存在冲突</translation>
<translation id="3885155851504623709">区</translation>
<translation id="3934680773876859118">无法加载 PDF 文档</translation>
<translation id="3963721102035795474">阅读器模式</translation>
<translation id="4030383055268325496">撤消添加(&amp;U)</translation>
-<translation id="4058922952496707368">“<ph name="SUBKEY"/>”键:<ph name="ERROR"/></translation>
+<translation id="404928562651467259">警告</translation>
+<translation id="4058922952496707368">“<ph name="SUBKEY" />”键:<ph name="ERROR" /></translation>
<translation id="4079302484614802869">代理配置已设置为使用 .pac 脚本网址,而不是固定的代理服务器。</translation>
<translation id="409504436206021213">不重新加载</translation>
<translation id="4103249731201008433">设备序列号无效</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">签名无效</translation>
<translation id="4269787794583293679">(无用户名)</translation>
<translation id="4300246636397505754">家长建议</translation>
-<translation id="4372948949327679948">应使用<ph name="VALUE_TYPE"/>值。</translation>
+<translation id="4325863107915753736">找不到文章</translation>
+<translation id="4372948949327679948">应使用<ph name="VALUE_TYPE" />值。</translation>
+<translation id="4377125064752653719">您尝试访问的是 <ph name="DOMAIN" />,但服务器出示的证书已被其颁发者吊销。这表明绝对不应该信任此服务器出示的安全凭据。您可能正在与攻击者进行通信。</translation>
+<translation id="4394049700291259645">停用</translation>
+<translation id="4424024547088906515">此服务器无法证明它是<ph name="DOMAIN" />;Chrome不信任其安全证书。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
<translation id="443673843213245140">已停用代理,但是指定了明确的代理配置。</translation>
-<translation id="4506176782989081258">验证错误:<ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">验证错误:<ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">从 Chrome 中移除地址?</translation>
<translation id="4594403342090139922">撤消删除(&amp;U)</translation>
<translation id="4607653538520819196">此网页不能由流量节省程序代理进行处理。</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">此服务器无法证明它是<ph name="DOMAIN" />;其安全证书有误。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
<translation id="4726672564094551039">重新加载政策</translation>
+<translation id="4728558894243024398">平台</translation>
+<translation id="4771973620359291008">发生未知错误。</translation>
<translation id="4800132727771399293">请检查您的到期日期和银行卡验证码 (CVC),然后重试</translation>
<translation id="4813512666221746211">网络错误</translation>
+<translation id="4816492930507672669">适合页面大小</translation>
<translation id="4850886885716139402">视图</translation>
-<translation id="4923417429809017348">翻译服务器已将此网页从某种未知语言翻译成了<ph name="LANGUAGE_LANGUAGE"/>。</translation>
+<translation id="4923417429809017348">翻译服务器已将此网页从某种未知语言翻译成了<ph name="LANGUAGE_LANGUAGE" />。</translation>
<translation id="4926049483395192435">必须指定。</translation>
<translation id="4968547170521245791">无法代理</translation>
-<translation id="498957508165411911">是否将<ph name="ORIGINAL_LANGUAGE"/>翻译成<ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">是否将<ph name="ORIGINAL_LANGUAGE" />翻译成<ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">后备存储状态不佳</translation>
<translation id="5031870354684148875">关于 Google 翻译</translation>
+<translation id="5045550434625856497">密码不正确</translation>
+<translation id="5087286274860437796">服务器的证书目前无效。</translation>
<translation id="5089810972385038852">州</translation>
+<translation id="5094747076828555589">此服务器无法证明它是<ph name="DOMAIN" />;Chromium不信任其安全证书。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
<translation id="5095208057601539847">省</translation>
<translation id="5145883236150621069">策略响应中存在错误代码</translation>
<translation id="5172758083709347301">本机</translation>
-<translation id="5179510805599951267">不是<ph name="ORIGINAL_LANGUAGE"/>?报告此错误</translation>
+<translation id="5179510805599951267">不是<ph name="ORIGINAL_LANGUAGE" />?报告此错误</translation>
<translation id="5190835502935405962">书签栏</translation>
+<translation id="5199729219167945352">实验</translation>
+<translation id="5251803541071282808">云端</translation>
<translation id="5295309862264981122">确认导航</translation>
<translation id="5299298092464848405">解析策略时出错</translation>
+<translation id="5316812925700871227">逆时针旋转</translation>
<translation id="5317780077021120954">保存</translation>
<translation id="536296301121032821">无法存储策略设置</translation>
-<translation id="5439770059721715174">“<ph name="ERROR_PATH"/>”中存在模式验证错误:<ph name="ERROR"/></translation>
+<translation id="540969355065856584">此服务器无法证明它是 <ph name="DOMAIN" />;其安全证书目前无效。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
+<translation id="5439770059721715174">“<ph name="ERROR_PATH" />”中存在模式验证错误:<ph name="ERROR" /></translation>
<translation id="5455374756549232013">策略时间戳无效</translation>
<translation id="5470861586879999274">恢复修改(&amp;R)</translation>
<translation id="5509780412636533143">受管理的书签</translation>
<translation id="5523118979700054094">政策名</translation>
<translation id="552553974213252141">提取的内容是否正确?</translation>
<translation id="5540224163453853">找不到请求的文章。</translation>
+<translation id="5556459405103347317">重新加载</translation>
<translation id="5565735124758917034">主动</translation>
<translation id="560412284261940334">不支持管理</translation>
<translation id="5629630648637658800">无法加载策略设置</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">当前用户</translation>
<translation id="5813119285467412249">恢复添加(&amp;R)</translation>
<translation id="5872918882028971132">家长建议</translation>
-<translation id="587701087903783706">关闭适合移动设备的视图</translation>
<translation id="59107663811261420">Google Payments 不支持使用这种类型的信用卡向此商家付款,请选择其他卡。</translation>
+<translation id="5975083100439434680">缩小</translation>
<translation id="5989320800837274978">固定代理服务器和 .pac 脚本网址均未指定。</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">关闭</translation>
+<translation id="6060685159320643512">请小心,这些实验性功能可能有风险</translation>
+<translation id="6151417162996330722">该服务器证书的有效期过长。</translation>
<translation id="6154808779448689242">返回的策略令牌与当前令牌不匹配</translation>
<translation id="6165508094623778733">了解详情</translation>
<translation id="6259156558325130047">恢复顺序调整(&amp;R)</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> 书签</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> 书签</translation>
<translation id="6282194474023008486">邮编</translation>
<translation id="6337534724793800597">按名称过滤政策</translation>
+<translation id="6387478394221739770">想试试超酷的 Chrome 新功能?欢迎访问 chrome.com/beta,试用我们的测试版!</translation>
+<translation id="6426993025560594914">所有实验功能均可在您的平台上使用!</translation>
<translation id="6445051938772793705">国家/地区</translation>
<translation id="6458467102616083041">由于默认搜索被政策停用,政策值已被忽略。</translation>
<translation id="647261751007945333">设备政策</translation>
<translation id="6512448926095770873">离开此页</translation>
<translation id="6529602333819889595">恢复删除(&amp;R)</translation>
<translation id="6550675742724504774">选项</translation>
-<translation id="6597614308054261376">您正在尝试访问 <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>。此网页目前不能由流量节省程序代理进行处理。</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> 搜索</translation>
+<translation id="6597614308054261376">您正在尝试访问 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />。此网页目前不能由流量节省程序代理进行处理。</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> 搜索</translation>
<translation id="6644283850729428850">此政策已弃用。</translation>
<translation id="6646897916597483132">输入信用卡正面显示的 4 位数银行卡验证码 (CVC)</translation>
+<translation id="674375294223700098">未知的服务器证书错误。</translation>
<translation id="6753269504797312559">政策值</translation>
<translation id="6831043979455480757">翻译</translation>
<translation id="6839929833149231406">地域</translation>
<translation id="6874604403660855544">恢复添加(&amp;R)</translation>
<translation id="6891596781022320156">政策级别不受支持。</translation>
<translation id="6915804003454593391">用户:</translation>
+<translation id="6957887021205513506">该服务器的证书似乎是伪造的。</translation>
<translation id="6965382102122355670">确定</translation>
<translation id="6965978654500191972">设备</translation>
<translation id="6970216967273061347">区</translation>
<translation id="6973656660372572881">固定代理服务器和 .pac 脚本网址均已指定。</translation>
<translation id="6980028882292583085">JavaScript 提醒</translation>
<translation id="7012363358306927923">中国银联</translation>
+<translation id="7050187094878475250">您尝试访问 <ph name="DOMAIN" />,但服务器提供的证书不可信(有效期过长)。</translation>
<translation id="7087282848513945231">县/郡</translation>
-<translation id="7108649287766967076">无法翻译成<ph name="TARGET_LANGUAGE"/>。</translation>
+<translation id="7108649287766967076">无法翻译成<ph name="TARGET_LANGUAGE" />。</translation>
<translation id="7139724024395191329">酋长国</translation>
+<translation id="7179921470347911571">立即重新启动</translation>
<translation id="7180611975245234373">刷新</translation>
<translation id="7182878459783632708">未设置任何政策</translation>
-<translation id="7186367841673660872">已将此网页从<ph name="ORIGINAL_LANGUAGE"/>翻译成<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="7186367841673660872">已将此网页从<ph name="ORIGINAL_LANGUAGE" />翻译成<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">用 <ph name="SITE_NAME"/> 搜索“<ph name="SEARCH_TERMS"/>”</translation>
+<translation id="7208899522964477531">用 <ph name="SITE_NAME" /> 搜索“<ph name="SEARCH_TERMS" />”</translation>
+<translation id="725866823122871198">您计算机的日期和时间(<ph name="DATE_AND_TIME" />)不正确,因此无法与 <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立私密连接。</translation>
<translation id="7275334191706090484">受管理的书签</translation>
<translation id="7298195798382681320">推荐</translation>
<translation id="7334320624316649418">恢复顺序调整(&amp;R)</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">强制</translation>
<translation id="7542995811387359312">由于该表单不使用安全连接,因此自动填写信用卡信息的功能已停用。</translation>
-<translation id="7568593326407688803">此网页为<ph name="ORIGINAL_LANGUAGE"/>网页,是否需要翻译?</translation>
+<translation id="7567204685887185387">此服务器无法证明它是<ph name="DOMAIN" />;其安全证书可能是由骗子发出的。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
+<translation id="7568593326407688803">此网页为<ph name="ORIGINAL_LANGUAGE" />网页,是否需要翻译?</translation>
<translation id="7569952961197462199">从 Chrome 中移除信用卡信息?</translation>
-<translation id="7600965453749440009">一律不翻译<ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">值超出了范围 (<ph name="VALUE"/>)。</translation>
+<translation id="7592362899630581445">服务器的证书违反了域名限制。</translation>
+<translation id="7600965453749440009">一律不翻译<ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">值超出了范围 (<ph name="VALUE" />)。</translation>
+<translation id="7674629440242451245">想试试超酷的 Chrome 新功能?欢迎访问 chrome.com/dev,试用我们的测试版!</translation>
<translation id="7752995774971033316">非托管</translation>
+<translation id="7761701407923456692">服务器的证书与网址不相符。</translation>
<translation id="777702478322588152">县</translation>
<translation id="7791543448312431591">添加</translation>
<translation id="7805768142964895445">状态</translation>
<translation id="7813600968533626083">从 Chrome 中移除表单建议?</translation>
<translation id="7887683347370398519">请检查您的银行卡验证码 (CVC),然后重试</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">服务器的证书尚未生效。</translation>
<translation id="7956713633345437162">移动设备书签</translation>
<translation id="7961015016161918242">一律不</translation>
<translation id="7977590112176369853">&lt;输入查询&gt;</translation>
-<translation id="7983301409776629893">一律将<ph name="ORIGINAL_LANGUAGE"/>翻译成<ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">一律将<ph name="ORIGINAL_LANGUAGE" />翻译成<ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">桌面书签</translation>
<translation id="7995512525968007366">未指定</translation>
-<translation id="8034522405403831421">此网页的源语言为<ph name="SOURCE_LANGUAGE"/>,要将其翻译成<ph name="TARGET_LANGUAGE"/>吗?</translation>
+<translation id="8003882219468422867">在企业环境中强制实施</translation>
+<translation id="8034522405403831421">此网页的源语言为<ph name="SOURCE_LANGUAGE" />,要将其翻译成<ph name="TARGET_LANGUAGE" />吗?</translation>
<translation id="8088680233425245692">无法查看文章。</translation>
<translation id="8091372947890762290">正等待在服务器上激活</translation>
<translation id="8194797478851900357">撤消移动(&amp;U)</translation>
-<translation id="8201077131113104583">ID 为“<ph name="EXTENSION_ID"/>”的扩展程序的更新网址无效。</translation>
+<translation id="8201077131113104583">ID 为“<ph name="EXTENSION_ID" />”的扩展程序的更新网址无效。</translation>
<translation id="8208216423136871611">不保存</translation>
<translation id="8218327578424803826">分配的位置:</translation>
<translation id="8249320324621329438">最后一次抓取时间:</translation>
+<translation id="8294431847097064396">来源</translation>
<translation id="8308427013383895095">由于网络连接问题,翻译失败。</translation>
<translation id="8311778656528046050">确定要重新加载此网页吗?</translation>
<translation id="8349305172487531364">书签栏</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">适用对象</translation>
<translation id="8530504477309582336">Google Payments 不支持这种类型的信用卡,请选择其他卡。</translation>
<translation id="8553075262323480129">系统无法确定该网页的语言,因此无法进行翻译。</translation>
-<translation id="8571890674111243710">正在将网页翻译成<ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">您设备的日期和时间(<ph name="DATE_AND_TIME" />)不正确,因此无法与 <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立私密连接。</translation>
+<translation id="8571890674111243710">正在将网页翻译成<ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">全部重置为默认值</translation>
<translation id="8713130696108419660">初始签名错误</translation>
<translation id="8725066075913043281">重试</translation>
+<translation id="8738058698779197622">要建立安全连接,您的时钟设置必须正确。这是因为,网站用于证明身份的证书仅在特定时间段有效。由于您设备的时钟不正确,因此 Chromium 无法验证这些证书。</translation>
<translation id="8790007591277257123">恢复删除(&amp;R)</translation>
<translation id="8804164990146287819">隐私权政策</translation>
+<translation id="8820817407110198400">书签</translation>
<translation id="8824019021993735287">Chrome 目前无法验证您的信用卡,请稍后重试。</translation>
<translation id="8834246243508017242">允许利用通讯录中的信息自动填充…</translation>
<translation id="883848425547221593">其他书签</translation>
+<translation id="884923133447025588">未找到任何吊销机制。</translation>
<translation id="8866481888320382733">解析策略设置时出错</translation>
<translation id="8876793034577346603">无法解析网络配置。</translation>
<translation id="8891727572606052622">代理模式无效。</translation>
-<translation id="8940229512486821554">运行 <ph name="EXTENSION_NAME"/> 命令:<ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">抱歉,此项实验性功能不能用于您的平台。</translation>
+<translation id="8903921497873541725">放大</translation>
+<translation id="8932102934695377596">您的时钟慢了</translation>
+<translation id="8940229512486821554">运行 <ph name="EXTENSION_NAME" /> 命令:<ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">服务器的证书已过期。</translation>
<translation id="8988760548304185580">输入信用卡背面显示的到期日期和 3 位数银行卡验证码 (CVC)</translation>
-<translation id="9020542370529661692">已将此网页内容翻译成<ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">应用于整个系统的设置只能由以下所有者设定:<ph name="OWNER_EMAIL" />。</translation>
+<translation id="9020542370529661692">已将此网页内容翻译成<ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">您试图访问 <ph name="DOMAIN" />,但服务器提供的证书无效。</translation>
<translation id="9125941078353557812">输入信用卡背面显示的 3 位数银行卡验证码 (CVC)</translation>
<translation id="9137013805542155359">显示原始网页</translation>
<translation id="9148507642005240123">撤消修改(&amp;U)</translation>
<translation id="9154176715500758432">留在此页</translation>
<translation id="9170848237812810038">撤消(&amp;U)</translation>
+<translation id="917450738466192189">服务器证书无效。</translation>
+<translation id="9187827965378254003">目前似乎没有任何实验。</translation>
<translation id="9207861905230894330">无法添加文章。</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">清除表单内容</translation>
+<translation id="988159990683914416">开发者内部版本</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_zh-TW.xtb b/chromium/components/strings/components_strings_zh-TW.xtb
index 8d8a90051e3..9519db18fa1 100644
--- a/chromium/components/strings/components_strings_zh-TW.xtb
+++ b/chromium/components/strings/components_strings_zh-TW.xtb
@@ -1,12 +1,18 @@
-<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="zh-TW">
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="zh-TW">
+<translation id="1032854598605920125">順時針旋轉</translation>
<translation id="1055184225775184556">復原新增(&amp;U)</translation>
<translation id="106701514854093668">電腦版書籤</translation>
-<translation id="1103523840287552314">一律翻譯<ph name="LANGUAGE"/></translation>
+<translation id="1080116354587839789">符合視窗寬度</translation>
+<translation id="1103523840287552314">一律翻譯<ph name="LANGUAGE" /></translation>
<translation id="1113869188872983271">復原重新排序(&amp;U)</translation>
<translation id="111844081046043029">您確定要離開此網頁嗎?</translation>
<translation id="112840717907525620">政策快取正確</translation>
<translation id="1132774398110320017">Chrome 自動填入設定...</translation>
-<translation id="1152921474424827756">存取 <ph name="URL"/> 的<ph name="BEGIN_LINK"/>頁庫存檔副本<ph name="END_LINK"/></translation>
+<translation id="1150979032973867961">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證未取得您電腦作業系統的信任。這可能是因為設定錯誤,或有攻擊者攔截您的連線所致。</translation>
+<translation id="1152921474424827756">存取 <ph name="URL" /> 的<ph name="BEGIN_LINK" />頁庫存檔副本<ph name="END_LINK" /></translation>
+<translation id="121201262018556460">您嘗試前往 <ph name="DOMAIN" />,但伺服器所提供的憑證含有防護力薄弱的金鑰。攻擊者可能已破壞私密金鑰,而該伺服器可能並非您的目標伺服器 (您的連線對象可能是攻擊者的電腦)。</translation>
<translation id="1227224963052638717">不明政策。</translation>
<translation id="1227633850867390598">隱藏政策值</translation>
<translation id="1228893227497259893">實體識別碼錯誤</translation>
@@ -14,65 +20,77 @@
<translation id="1339601241726513588">註冊網域:</translation>
<translation id="1344588688991793829">Chromium 自動填入設定...</translation>
<translation id="1426410128494586442">是</translation>
+<translation id="1430915738399379752">列印</translation>
<translation id="1455235771979731432">驗證您的信用卡時發生問題。請檢查網際網路連線,然後再試一次。</translation>
<translation id="1491151370853475546">重新載入這個網頁</translation>
<translation id="1549470594296187301">您必須啟用 JavaScript 才能使用這項功能。</translation>
-<translation id="1639239467298939599">載入中</translation>
<translation id="1640180200866533862">使用者政策</translation>
<translation id="1644184664548287040">網路設定無效,無法匯入。</translation>
-<translation id="1693754753824026215"><ph name="SITE"/> 的網頁顯示:</translation>
+<translation id="1655462015569774233">{1,plural, =1{這個伺服器無法證明所在網域是 <ph name="DOMAIN" />;伺服器的安全性憑證已在昨天過期。這可能是因為設定錯誤,或是有攻擊者攔截您的連線。您電腦的時鐘目前設為 <ph name="CURRENT_DATE" />,這是正確的時間嗎?如果不是的話,請更新系統時鐘,然後重新整理這個網頁。}other{這個伺服器無法證明所在網域是 <ph name="DOMAIN" />;伺服器的安全性憑證已在 # 天前過期。這可能是因為設定錯誤,或是有攻擊者攔截您的連線。您電腦的時鐘目前設為 <ph name="CURRENT_DATE" />,這是正確的時間嗎?如果不是的話,請更新系統時鐘,然後重新整理這個網頁。}}</translation>
+<translation id="168841957122794586">伺服器憑證含有防護力薄弱的加密編譯金鑰。</translation>
+<translation id="1693754753824026215"><ph name="SITE" /> 的網頁顯示:</translation>
+<translation id="1706954506755087368">{1,plural, =1{這個伺服器無法證明所在網域是 <ph name="DOMAIN" />;伺服器的安全性憑證預定明天才生效。這可能是因為設定錯誤,或是有攻擊者攔截您的連線。}other{這個伺服器無法證明所在網域是 <ph name="DOMAIN" />;伺服器的安全性憑證預定 # 天後才生效。這可能是因為設定錯誤,或是有攻擊者攔截您的連線。}}</translation>
<translation id="1734864079702812349">Amex</translation>
+<translation id="1763864636252898013">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證未取得您裝置作業系統的信任。這可能是因為設定錯誤,或有攻擊者攔截您的連線所致。</translation>
<translation id="1821930232296380041">要求或要求參數無效</translation>
-<translation id="1853748787962613237">無法顯示文章。</translation>
<translation id="1871208020102129563">Proxy 設定為使用固定的 Proxy 伺服器,而非 .pac 指令碼網址。</translation>
-<translation id="1875753206475436906">啟發式演算法類型:<ph name="HEURISTIC_TYPE"/>
- 伺服器類型:<ph name="SERVER_TYPE"/>
- 欄位簽名:<ph name="FIELD_SIGNATURE"/>
- 表單簽名:<ph name="FORM_SIGNATURE"/>
- 實驗 ID:「<ph name="EXPERIMENT_ID"/>」</translation>
-<translation id="194030505837763158">前往 <ph name="LINK"/></translation>
-<translation id="1962204205936693436"><ph name="DOMAIN"/> 書籤</translation>
+<translation id="194030505837763158">前往 <ph name="LINK" /></translation>
+<translation id="1962204205936693436"><ph name="DOMAIN" /> 書籤</translation>
<translation id="1973335181906896915">序列化錯誤</translation>
+<translation id="1974060860693918893">進階</translation>
<translation id="2025186561304664664">Proxy 已設為自動設定。</translation>
<translation id="2025623846716345241">確認重新載入</translation>
-<translation id="2030481566774242610">您要找的是 <ph name="LINK"/> 嗎?</translation>
+<translation id="2030481566774242610">您要找的是 <ph name="LINK" /> 嗎?</translation>
<translation id="2053553514270667976">郵遞區號</translation>
<translation id="20817612488360358">雖然系統 Proxy 設定已設為使用,不過也指定了明確 Proxy 設定。</translation>
<translation id="2094505752054353250">網域不符</translation>
<translation id="2096368010154057602">省</translation>
<translation id="2113977810652731515">信用卡</translation>
-<translation id="2114841414352855701">由於政策被「<ph name="POLICY_NAME"/>」覆寫了,因此遭到略過。</translation>
+<translation id="2114841414352855701">由於政策被「<ph name="POLICY_NAME" />」覆寫了,因此遭到略過。</translation>
+<translation id="2128531968068887769">Native Client</translation>
<translation id="213826338245044447">行動版書籤</translation>
+<translation id="2171101176734966184">您嘗試前往 <ph name="DOMAIN" />,但該伺服器提供的憑證是以防護力較弱的簽章演算法進行簽署,這代表該伺服器提供的安全認證可能遭到偽造,且該伺服器可能並非您的目標伺服器 (您的連線對象可能是攻擊者的電腦)。</translation>
<translation id="2181821976797666341">政策</translation>
<translation id="2212735316055980242">找不到政策</translation>
<translation id="2213606439339815911">正在擷取項目...</translation>
<translation id="225207911366869382">這個政策值已遭汰換。</translation>
<translation id="2262243747453050782">HTTP 錯誤</translation>
-<translation id="2270192940992995399">找不到文章。</translation>
-<translation id="2328300916057834155">已忽略索引「<ph name="ENTRY_INDEX"/>」的無效書籤</translation>
+<translation id="2282872951544483773">無法使用的實驗性功能</translation>
+<translation id="229702904922032456">根憑證或中繼憑證已過期。</translation>
+<translation id="2328300916057834155">已忽略索引「<ph name="ENTRY_INDEX" />」的無效書籤</translation>
<translation id="2354001756790975382">其他書籤</translation>
<translation id="2359808026110333948">繼續</translation>
<translation id="2367567093518048410">等級</translation>
+<translation id="2384307209577226199">企業預設</translation>
+<translation id="2386255080630008482">伺服器憑證已遭撤銷。</translation>
<translation id="2392959068659972793">顯示尚未設定任何值的政策</translation>
<translation id="2396249848217231973">復原刪除(&amp;U)</translation>
+<translation id="2413528052993050574">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證已遭撤銷。這可能是因為設定錯誤,或有攻擊者攔截您的連線所致。</translation>
<translation id="2455981314101692989">這個網頁已停用這個表單的自動填入功能。</translation>
<translation id="2479410451996844060">無效的搜尋網址。</translation>
+<translation id="2491120439723279231">伺服器憑證含有錯誤。</translation>
<translation id="2495083838625180221">JSON 剖析器</translation>
<translation id="2498091847651709837">掃描新信用卡</translation>
<translation id="2556876185419854533">復原編輯(&amp;U)</translation>
-<translation id="2581221116934462656">您下次要讓 <ph name="PRODUCT_NAME"/> 翻譯這個網站的<ph name="LANGUAGE_NAME"/>網頁嗎?</translation>
+<translation id="2581221116934462656">您下次要讓 <ph name="PRODUCT_NAME" /> 翻譯這個網站的<ph name="LANGUAGE_NAME" />網頁嗎?</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">此文件受到密碼保護,請輸入密碼。</translation>
+<translation id="2625385379895617796">您的時鐘時間過快</translation>
<translation id="2639739919103226564">狀態:</translation>
+<translation id="2653659639078652383">提交</translation>
<translation id="2704283930420550640">政策值格式不符。</translation>
<translation id="2721148159707890343">要求成功</translation>
+<translation id="2728127805433021124">伺服器憑證是以防護力較弱的簽章演算法進行簽署。</translation>
<translation id="2774256287122201187">您可以繼續操作。如果您繼續造訪網頁,後續 5 分鐘內將不會再看到這項警告。</translation>
<translation id="277499241957683684">沒有裝置紀錄</translation>
<translation id="2835170189407361413">清除表單</translation>
-<translation id="2855922900409897335">驗證您的 <ph name="CREDIT_CARD"/></translation>
+<translation id="2855922900409897335">驗證您的 <ph name="CREDIT_CARD" /></translation>
+<translation id="2915500479781995473">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證已過期。這可能是因為設定錯誤,或有攻擊者攔截您的連線所致。您電腦時鐘目前設定的時間是 <ph name="CURRENT_TIME" />,是否正確?如果設定有誤,請更正您系統的時鐘,再重新整理這個頁面。</translation>
+<translation id="2922350208395188000">無法檢查伺服器憑證。</translation>
+<translation id="2941952326391522266">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證來自 <ph name="DOMAIN2" /> 網域。這可能是因為設定錯誤,或有攻擊者攔截您的連線所致。</translation>
<translation id="2958431318199492670">網路設定未遵循 ONC 標準,系統可能無法匯入部分設定。</translation>
<translation id="2972581237482394796">重做(&amp;R)</translation>
-<translation id="3010559122411665027">清單項目「<ph name="ENTRY_INDEX"/>」:<ph name="ERROR"/></translation>
+<translation id="3010559122411665027">清單項目「<ph name="ENTRY_INDEX" />」:<ph name="ERROR" /></translation>
<translation id="3024663005179499861">政策類型有誤</translation>
<translation id="3105172416063519923">資產 ID:</translation>
<translation id="3145945101586104090">無法將回應解碼</translation>
@@ -80,32 +98,42 @@
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">島</translation>
<translation id="3219579145727097045">請輸入有效期限和信用卡正面的四位數信用卡安全碼</translation>
-<translation id="3228969707346345236">網頁已經是<ph name="LANGUAGE"/>,翻譯作業失敗。</translation>
+<translation id="3225919329040284222">伺服器呈現的憑證與內建的預期條件不符。我們在系統中針對特定高安全性的網站內建了這些預期條件,目的在於保護您的資料安全無虞。</translation>
+<translation id="3228969707346345236">網頁已經是<ph name="LANGUAGE" />,翻譯作業失敗。</translation>
<translation id="3270847123878663523">復原重新排序(&amp;U)</translation>
+<translation id="3286538390144397061">立即重新啟動</translation>
<translation id="333371639341676808">防止此網頁產生其他對話方塊。</translation>
-<translation id="3369366829301677151">更新並驗證您的 <ph name="CREDIT_CARD"/></translation>
+<translation id="3340978935015468852">設定</translation>
+<translation id="3369192424181595722">時鐘錯誤</translation>
+<translation id="3369366829301677151">更新並驗證您的 <ph name="CREDIT_CARD" /></translation>
<translation id="337363190475750230">已取消佈建</translation>
<translation id="3377188786107721145">政策解析錯誤</translation>
<translation id="3380365263193509176">未知的錯誤</translation>
<translation id="3380864720620200369">用戶端 ID:</translation>
<translation id="3427342743765426898">重做編輯(&amp;R)</translation>
+<translation id="3435896845095436175">啟用</translation>
<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">擷取間隔:</translation>
+<translation id="3462200631372590220">隱藏詳細資料</translation>
+<translation id="3528171143076753409">伺服器憑證授權不可靠。</translation>
<translation id="3542684924769048008">選擇密碼:</translation>
<translation id="3583757800736429874">重做移動(&amp;R)</translation>
<translation id="3623476034248543066">顯示政策值</translation>
+<translation id="3648607100222897006">這些實驗性功能隨時都有可能變動、中斷或消失。我們完全無法保證啟用這些實驗性功能會導致何種後果,您的瀏覽器說不定會突然自己燒掉。當然這只是玩笑話,不過您的瀏覽器可能真的會刪除您的所有資料,或是意外洩漏您的安全性和隱私權設定。只要您啟用了任何實驗性功能,這個瀏覽器的所有使用者都會啟用該功能。使用時請務必小心謹慎。</translation>
<translation id="3650584904733503804">驗證成功</translation>
<translation id="370665806235115550">載入中…</translation>
<translation id="3712624925041724820">授權已用盡</translation>
<translation id="3739623965217189342">您複製的連結</translation>
<translation id="375403751935624634">伺服器錯誤,翻譯作業失敗。</translation>
<translation id="385051799172605136">返回</translation>
+<translation id="3858027520442213535">更新日期和時間</translation>
<translation id="3884278016824448484">裝置識別碼發生衝突</translation>
<translation id="3885155851504623709">轄區</translation>
<translation id="3934680773876859118">無法載入 PDF 文件</translation>
<translation id="3963721102035795474">閱讀器模式</translation>
<translation id="4030383055268325496">復原新增(&amp;U)</translation>
-<translation id="4058922952496707368">鍵「<ph name="SUBKEY"/>」:<ph name="ERROR"/></translation>
+<translation id="404928562651467259">警告</translation>
+<translation id="4058922952496707368">鍵「<ph name="SUBKEY" />」:<ph name="ERROR" /></translation>
<translation id="4079302484614802869">Proxy 設定已設為使用 .pac 指令碼網址,而非固定的 Proxy 伺服器。</translation>
<translation id="409504436206021213">不要重新載入</translation>
<translation id="4103249731201008433">裝置序號無效</translation>
@@ -118,40 +146,56 @@
<translation id="4258748452823770588">簽名有誤</translation>
<translation id="4269787794583293679">(沒有使用者名稱)</translation>
<translation id="4300246636397505754">家長建議</translation>
-<translation id="4372948949327679948">預期的「<ph name="VALUE_TYPE"/>」值。</translation>
+<translation id="4325863107915753736">找不到文章</translation>
+<translation id="4372948949327679948">預期的「<ph name="VALUE_TYPE" />」值。</translation>
+<translation id="4377125064752653719">您嘗試前往 <ph name="DOMAIN" />,但是發行者已撤銷伺服器提供的憑證。在這種情況下,請勿信任伺服器提供的安全性憑證,因為您的連線對象可能是攻擊者的電腦。</translation>
+<translation id="4394049700291259645">停用</translation>
+<translation id="4424024547088906515">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證未取得 Chrome 的信任。這可能是因為設定錯誤,或有攻擊者攔截您的連線所致。</translation>
<translation id="443673843213245140">雖然已停用 Proxy,不過已指定明確 Proxy 設定。</translation>
-<translation id="4506176782989081258">驗證錯誤:<ph name="VALIDATION_ERROR"/></translation>
+<translation id="4506176782989081258">驗證錯誤:<ph name="VALIDATION_ERROR" /></translation>
<translation id="4587425331216688090">要從 Chrome 中移除地址嗎?</translation>
<translation id="4594403342090139922">復原刪除(&amp;U)</translation>
<translation id="4607653538520819196">Data Saver 無法對這個網頁執行 Proxy 處理。</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證含有錯誤。這可能是因為設定錯誤,或有攻擊者攔截您的連線所致。</translation>
<translation id="4726672564094551039">重新載入政策</translation>
+<translation id="4728558894243024398">平台</translation>
+<translation id="4771973620359291008">發生不明的錯誤。</translation>
<translation id="4800132727771399293">請檢查您的有效期限和信用卡安全碼,然後再試一次</translation>
<translation id="4813512666221746211">網路錯誤</translation>
+<translation id="4816492930507672669">依頁面大小自動調整</translation>
<translation id="4850886885716139402">檢視</translation>
-<translation id="4923417429809017348">系統已將此網頁從不明語言翻譯成<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="4923417429809017348">系統已將此網頁從不明語言翻譯成<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4926049483395192435">必須指定。</translation>
<translation id="4968547170521245791">無法執行 Proxy 處理</translation>
-<translation id="498957508165411911">將網頁內容由<ph name="ORIGINAL_LANGUAGE"/>翻譯成<ph name="TARGET_LANGUAGE"/>?</translation>
+<translation id="498957508165411911">將網頁內容由<ph name="ORIGINAL_LANGUAGE" />翻譯成<ph name="TARGET_LANGUAGE" />?</translation>
<translation id="5019198164206649151">備份儲存狀態不佳</translation>
<translation id="5031870354684148875">關於「Google 翻譯」</translation>
+<translation id="5045550434625856497">密碼不正確</translation>
+<translation id="5087286274860437796">伺服器憑證目前無效。</translation>
<translation id="5089810972385038852">州</translation>
+<translation id="5094747076828555589">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證未取得 Chromium 的信任。這可能是因為設定錯誤,或有攻擊者攔截您的連線所致。</translation>
<translation id="5095208057601539847">省</translation>
<translation id="5145883236150621069">政策回應中存在錯誤代碼</translation>
<translation id="5172758083709347301">本機</translation>
-<translation id="5179510805599951267">網頁內容不是<ph name="ORIGINAL_LANGUAGE"/>嗎?請回報此錯誤</translation>
+<translation id="5179510805599951267">網頁內容不是<ph name="ORIGINAL_LANGUAGE" />嗎?請回報此錯誤</translation>
<translation id="5190835502935405962">書籤列</translation>
+<translation id="5199729219167945352">實驗性功能</translation>
+<translation id="5251803541071282808">雲端</translation>
<translation id="5295309862264981122">確認瀏覽</translation>
<translation id="5299298092464848405">解析政策時發生錯誤</translation>
+<translation id="5316812925700871227">逆時針旋轉</translation>
<translation id="5317780077021120954">儲存</translation>
<translation id="536296301121032821">無法儲存政策設定</translation>
-<translation id="5439770059721715174">「<ph name="ERROR_PATH"/>」發生架構驗證錯誤:<ph name="ERROR"/></translation>
+<translation id="540969355065856584">這個伺服器無法證明所屬網域為 <ph name="DOMAIN" />;其安全性憑證目前無效。這可能是因為設定錯誤,或是有攻擊者攔截您的連線所致。</translation>
+<translation id="5439770059721715174">「<ph name="ERROR_PATH" />」發生架構驗證錯誤:<ph name="ERROR" /></translation>
<translation id="5455374756549232013">政策時間戳記有誤</translation>
<translation id="5470861586879999274">重做編輯(&amp;R)</translation>
<translation id="5509780412636533143">受管理書籤</translation>
<translation id="5523118979700054094">政策名稱</translation>
<translation id="552553974213252141">擷取的文字是否正確?</translation>
<translation id="5540224163453853">找不到要求的文章。</translation>
+<translation id="5556459405103347317">重新載入</translation>
<translation id="5565735124758917034">管理中</translation>
<translation id="560412284261940334">系統不支援管理</translation>
<translation id="5629630648637658800">無法載入政策設定</translation>
@@ -159,46 +203,56 @@
<translation id="5720705177508910913">目前使用者</translation>
<translation id="5813119285467412249">重做新增(&amp;R)</translation>
<translation id="5872918882028971132">家長建議</translation>
-<translation id="587701087903783706">關閉適合透過行動裝置瀏覽的檢視模式</translation>
<translation id="59107663811261420">這個商家的 Google Payments 不支援此類型卡片,請選取其他卡片。</translation>
+<translation id="5975083100439434680">縮小</translation>
<translation id="5989320800837274978">沒有指定固定的 Proxy 伺服器和 .pac 指令碼網址。</translation>
<translation id="6008256403891681546">JCB</translation>
+<translation id="6040143037577758943">關閉</translation>
+<translation id="6060685159320643512">請注意,這些實驗性功能可能對電腦有害</translation>
+<translation id="6151417162996330722">伺服器憑證的有效期限太長。</translation>
<translation id="6154808779448689242">傳回的政策符記與目前符記不相符</translation>
<translation id="6165508094623778733">瞭解詳情</translation>
<translation id="6259156558325130047">重做重新排序(&amp;R)</translation>
-<translation id="6263376278284652872"><ph name="DOMAIN"/> 書籤</translation>
+<translation id="6263376278284652872"><ph name="DOMAIN" /> 書籤</translation>
<translation id="6282194474023008486">郵遞區號</translation>
<translation id="6337534724793800597">依名稱篩選政策</translation>
+<translation id="6387478394221739770">想搶先試用酷炫的 Chrome 新功能嗎?請前往 chrome.com/beta 安裝測試版。</translation>
+<translation id="6426993025560594914">您的平台可以使用所有實驗性功能!</translation>
<translation id="6445051938772793705">國家/地區</translation>
<translation id="6458467102616083041">由於政策停用了預設搜尋,因此遭到略過。</translation>
<translation id="647261751007945333">裝置政策</translation>
<translation id="6512448926095770873">離開此頁</translation>
<translation id="6529602333819889595">重做刪除(&amp;R)</translation>
<translation id="6550675742724504774">選項</translation>
-<translation id="6597614308054261376">您嘗試連線至 <ph name="BEGIN_BOLD"/><ph name="SITE"/><ph name="END_BOLD"/>。Data Saver 目前無法對這個網頁執行 Proxy 處理。</translation>
-<translation id="6628463337424475685"><ph name="ENGINE"/> 搜尋</translation>
+<translation id="6597614308054261376">您嘗試連線至 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />。Data Saver 目前無法對這個網頁執行 Proxy 處理。</translation>
+<translation id="6628463337424475685"><ph name="ENGINE" /> 搜尋</translation>
<translation id="6644283850729428850">這項政策已遭取代。</translation>
<translation id="6646897916597483132">請輸入信用卡正面的四位數信用卡安全碼</translation>
+<translation id="674375294223700098">不明的伺服器憑證錯誤。</translation>
<translation id="6753269504797312559">政策值</translation>
<translation id="6831043979455480757">翻譯</translation>
<translation id="6839929833149231406">區</translation>
<translation id="6874604403660855544">重做新增(&amp;R)</translation>
<translation id="6891596781022320156">系統不支援這項政策的層級。</translation>
<translation id="6915804003454593391">使用者:</translation>
+<translation id="6957887021205513506">伺服器憑證疑似偽造。</translation>
<translation id="6965382102122355670">確定</translation>
<translation id="6965978654500191972">裝置</translation>
<translation id="6970216967273061347">區</translation>
<translation id="6973656660372572881">已指定固定的 Proxy 伺服器和 .pac 指令碼網址。</translation>
<translation id="6980028882292583085">JavaScript 通知</translation>
<translation id="7012363358306927923">中國銀聯</translation>
+<translation id="7050187094878475250">您嘗試連線至 <ph name="DOMAIN" />,但伺服器提供的憑證有效期限太長,因此難以信任。</translation>
<translation id="7087282848513945231">郡</translation>
-<translation id="7108649287766967076">無法將網頁內容翻譯成<ph name="TARGET_LANGUAGE"/>。</translation>
+<translation id="7108649287766967076">無法將網頁內容翻譯成<ph name="TARGET_LANGUAGE" />。</translation>
<translation id="7139724024395191329">大公國</translation>
+<translation id="7179921470347911571">立即重新啟動</translation>
<translation id="7180611975245234373">重新整理</translation>
<translation id="7182878459783632708">沒有設定任何政策</translation>
-<translation id="7186367841673660872">此網頁內容已由<ph name="ORIGINAL_LANGUAGE"/>翻譯成<ph name="LANGUAGE_LANGUAGE"/></translation>
+<translation id="7186367841673660872">此網頁內容已由<ph name="ORIGINAL_LANGUAGE" />翻譯成<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="719464814642662924">Visa</translation>
-<translation id="7208899522964477531">在 <ph name="SITE_NAME"/> 上搜尋 <ph name="SEARCH_TERMS"/></translation>
+<translation id="7208899522964477531">在 <ph name="SITE_NAME" /> 上搜尋 <ph name="SEARCH_TERMS" /></translation>
+<translation id="725866823122871198">您電腦的日期和時間 (<ph name="DATE_AND_TIME" />) 不正確,因此無法與 <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立私人連線。</translation>
<translation id="7275334191706090484">受管理書籤</translation>
<translation id="7298195798382681320">建議採用</translation>
<translation id="7334320624316649418">重做重新排序(&amp;R)</translation>
@@ -209,31 +263,38 @@
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7537536606612762813">強制</translation>
<translation id="7542995811387359312">由於這個表單並未採用加密連線方式,所以信用卡自動填入功能已停用。</translation>
-<translation id="7568593326407688803">此網頁為<ph name="ORIGINAL_LANGUAGE"/>您要翻譯網頁內容嗎?</translation>
+<translation id="7567204685887185387">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證是以欺詐方式發行。這可能是因為設定錯誤,或有攻擊者攔截您的連線所致。</translation>
+<translation id="7568593326407688803">此網頁為<ph name="ORIGINAL_LANGUAGE" />您要翻譯網頁內容嗎?</translation>
<translation id="7569952961197462199">要從 Chrome 中移除信用卡嗎?</translation>
-<translation id="7600965453749440009">一律不翻譯<ph name="LANGUAGE"/></translation>
-<translation id="7610193165460212391">值超出 <ph name="VALUE"/> 的範圍。</translation>
+<translation id="7592362899630581445">伺服器憑證的名稱不符合限制。</translation>
+<translation id="7600965453749440009">一律不翻譯<ph name="LANGUAGE" /></translation>
+<translation id="7610193165460212391">值超出 <ph name="VALUE" /> 的範圍。</translation>
+<translation id="7674629440242451245">想搶先試用酷炫的 Chrome 新功能嗎?請前往 chrome.com/dev 安裝開發人員版。</translation>
<translation id="7752995774971033316">未管理</translation>
+<translation id="7761701407923456692">伺服器憑證與網址不符。</translation>
<translation id="777702478322588152">縣</translation>
<translation id="7791543448312431591">新增</translation>
<translation id="7805768142964895445">狀態</translation>
<translation id="7813600968533626083">要從 Chrome 中移除建議嗎?</translation>
<translation id="7887683347370398519">請檢查您的 CVC,然後再試一次</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
+<translation id="7938958445268990899">伺服器憑證尚未生效。</translation>
<translation id="7956713633345437162">行動版書籤</translation>
<translation id="7961015016161918242">永不</translation>
<translation id="7977590112176369853">&lt;輸入查詢&gt;</translation>
-<translation id="7983301409776629893">一律將網頁內容由<ph name="ORIGINAL_LANGUAGE"/>翻譯成<ph name="TARGET_LANGUAGE"/></translation>
+<translation id="7983301409776629893">一律將網頁內容由<ph name="ORIGINAL_LANGUAGE" />翻譯成<ph name="TARGET_LANGUAGE" /></translation>
<translation id="7988324688042446538">電腦版書籤</translation>
<translation id="7995512525968007366">未指定</translation>
-<translation id="8034522405403831421">這個網頁的內容是<ph name="SOURCE_LANGUAGE"/>,需要翻譯成<ph name="TARGET_LANGUAGE"/>嗎?</translation>
+<translation id="8003882219468422867">企業覆寫</translation>
+<translation id="8034522405403831421">這個網頁的內容是<ph name="SOURCE_LANGUAGE" />,需要翻譯成<ph name="TARGET_LANGUAGE" />嗎?</translation>
<translation id="8088680233425245692">無法查看文章。</translation>
<translation id="8091372947890762290">尚未在伺服器上啟動</translation>
<translation id="8194797478851900357">復原移動(&amp;U)</translation>
-<translation id="8201077131113104583">擴充功能 (ID:「<ph name="EXTENSION_ID"/>」) 的更新網址無效。</translation>
+<translation id="8201077131113104583">擴充功能 (ID:「<ph name="EXTENSION_ID" />」) 的更新網址無效。</translation>
<translation id="8208216423136871611">不要儲存</translation>
<translation id="8218327578424803826">指派的位置:</translation>
<translation id="8249320324621329438">上次擷取時間:</translation>
+<translation id="8294431847097064396">來源</translation>
<translation id="8308427013383895095">網路連線發生問題,翻譯作業失敗。</translation>
<translation id="8311778656528046050">您確定要重新載入這個網頁?</translation>
<translation id="8349305172487531364">書籤列</translation>
@@ -242,25 +303,40 @@
<translation id="8488350697529856933">適用對象</translation>
<translation id="8530504477309582336">Google Payments 不支援此類型卡片,請選取其他卡片。</translation>
<translation id="8553075262323480129">無法判定網頁的語言,翻譯作業失敗。</translation>
-<translation id="8571890674111243710">正在將網頁翻譯成<ph name="LANGUAGE"/>...</translation>
+<translation id="8559762987265718583">您裝置的日期和時間 (<ph name="DATE_AND_TIME" />) 不正確,因此無法與 <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立私人連線。</translation>
+<translation id="8571890674111243710">正在將網頁翻譯成<ph name="LANGUAGE" />...</translation>
+<translation id="8647750283161643317">全部重設為預設值</translation>
<translation id="8713130696108419660">初始簽名錯誤</translation>
<translation id="8725066075913043281">再試一次</translation>
+<translation id="8738058698779197622">您必須正確設定時鐘,才能建立安全連線。這是因為網站驗證身分時所使用的憑證僅於特定一段時間內有效。由於您裝置的時鐘不正確,因此 Chromium 無法驗證這些憑證。</translation>
<translation id="8790007591277257123">重做刪除(&amp;R)</translation>
<translation id="8804164990146287819">隱私權政策</translation>
+<translation id="8820817407110198400">書籤</translation>
<translation id="8824019021993735287">Chrome 目前無法驗證您的信用卡,請稍後再試。</translation>
<translation id="8834246243508017242">啟用「使用聯絡人資料自動填入」功能…</translation>
<translation id="883848425547221593">其他書籤</translation>
+<translation id="884923133447025588">未發現撤銷機制。</translation>
<translation id="8866481888320382733">解析政策設定時發生錯誤</translation>
<translation id="8876793034577346603">無法解析網路設定。</translation>
<translation id="8891727572606052622">Proxy 模式無效。</translation>
-<translation id="8940229512486821554">執行 <ph name="EXTENSION_NAME"/> 指令:<ph name="SEARCH_TERMS"/></translation>
+<translation id="889901481107108152">很抱歉,這項實驗功能無法支援您的平台。</translation>
+<translation id="8903921497873541725">放大</translation>
+<translation id="8932102934695377596">您的時鐘時間過慢</translation>
+<translation id="8940229512486821554">執行 <ph name="EXTENSION_NAME" /> 指令:<ph name="SEARCH_TERMS" /></translation>
+<translation id="8971063699422889582">伺服器憑證已過期。</translation>
<translation id="8988760548304185580">請輸入有效期限和信用卡背面的三位數信用卡安全碼</translation>
-<translation id="9020542370529661692">此網頁內容已翻譯成<ph name="TARGET_LANGUAGE"/></translation>
+<translation id="901974403500617787">這些設定會套用至整個系統,只有以下使用者可設定:<ph name="OWNER_EMAIL" />。</translation>
+<translation id="9020542370529661692">此網頁內容已翻譯成<ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9049981332609050619">您嘗試連線至 <ph name="DOMAIN" />,但伺服器提供的憑證無效。</translation>
<translation id="9125941078353557812">請輸入信用卡背面的三位數信用卡安全碼</translation>
<translation id="9137013805542155359">顯示原文</translation>
<translation id="9148507642005240123">復原編輯(&amp;U)</translation>
<translation id="9154176715500758432">停留在此頁</translation>
<translation id="9170848237812810038">取消(&amp;U)</translation>
+<translation id="917450738466192189">伺服器憑證無效。</translation>
+<translation id="9187827965378254003">哎呀,目前似乎沒有可用的實驗功能。</translation>
<translation id="9207861905230894330">無法新增文章。</translation>
<translation id="933712198907837967">Diners Club</translation>
+<translation id="935608979562296692">清除表單</translation>
+<translation id="988159990683914416">開發人員版本</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/suggestions.gypi b/chromium/components/suggestions.gypi
index 2f91f39d4a5..7be7e725e75 100644
--- a/chromium/components/suggestions.gypi
+++ b/chromium/components/suggestions.gypi
@@ -16,6 +16,7 @@
'../net/net.gyp:net',
'../ui/gfx/gfx.gyp:gfx',
'../url/url.gyp:url_lib',
+ 'components.gyp:data_use_measurement_core',
'components.gyp:keyed_service_core',
'components.gyp:pref_registry',
'components.gyp:variations',
diff --git a/chromium/components/sync_driver.gypi b/chromium/components/sync_driver.gypi
index 86f14d25c51..a4428648961 100644
--- a/chromium/components/sync_driver.gypi
+++ b/chromium/components/sync_driver.gypi
@@ -10,16 +10,31 @@
'type': 'static_library',
'dependencies': [
'../base/base.gyp:base',
+ '../net/net.gyp:net',
'../sync/sync.gyp:sync',
+ '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation',
+ '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_proto_cpp',
+ '../ui/gfx/gfx.gyp:gfx',
+ 'favicon_core',
+ 'history_core_browser',
+ 'invalidation_public',
'os_crypt',
+ 'signin_core_browser',
+ 'version_info',
],
'include_dirs': [
'..',
],
'sources': [
# Note: file list duplicated in GN build.
+ 'sync_driver/about_sync_util.cc',
+ 'sync_driver/about_sync_util.h',
'sync_driver/backend_data_type_configurer.cc',
'sync_driver/backend_data_type_configurer.h',
+ 'sync_driver/backend_migrator.cc',
+ 'sync_driver/backend_migrator.h',
+ 'sync_driver/backup_rollback_controller.cc',
+ 'sync_driver/backup_rollback_controller.h',
'sync_driver/change_processor.cc',
'sync_driver/change_processor.h',
'sync_driver/data_type_controller.cc',
@@ -41,42 +56,90 @@
'sync_driver/device_info_sync_service.cc',
'sync_driver/device_info_sync_service.h',
'sync_driver/device_info_tracker.h',
+ 'sync_driver/directory_data_type_controller.cc',
+ 'sync_driver/directory_data_type_controller.h',
+ 'sync_driver/favicon_cache.cc',
+ 'sync_driver/favicon_cache.h',
+ 'sync_driver/frontend_data_type_controller.cc',
+ 'sync_driver/frontend_data_type_controller.h',
'sync_driver/generic_change_processor.cc',
'sync_driver/generic_change_processor.h',
'sync_driver/generic_change_processor_factory.cc',
'sync_driver/generic_change_processor_factory.h',
+ 'sync_driver/glue/browser_thread_model_worker.cc',
+ 'sync_driver/glue/browser_thread_model_worker.h',
+ 'sync_driver/glue/history_model_worker.cc',
+ 'sync_driver/glue/history_model_worker.h',
'sync_driver/glue/synced_session.cc',
'sync_driver/glue/synced_session.h',
+ 'sync_driver/glue/synced_window_delegate.h',
+ 'sync_driver/glue/typed_url_model_associator.cc',
+ 'sync_driver/glue/typed_url_model_associator.h',
+ 'sync_driver/glue/ui_model_worker.cc',
+ 'sync_driver/glue/ui_model_worker.h',
+ 'sync_driver/invalidation_adapter.cc',
+ 'sync_driver/invalidation_adapter.h',
+ 'sync_driver/invalidation_helper.cc',
+ 'sync_driver/invalidation_helper.h',
'sync_driver/local_device_info_provider.h',
'sync_driver/model_association_manager.cc',
'sync_driver/model_association_manager.h',
'sync_driver/model_associator.h',
'sync_driver/non_blocking_data_type_controller.cc',
'sync_driver/non_blocking_data_type_controller.h',
- 'sync_driver/non_blocking_data_type_manager.cc',
- 'sync_driver/non_blocking_data_type_manager.h',
'sync_driver/non_ui_data_type_controller.cc',
'sync_driver/non_ui_data_type_controller.h',
'sync_driver/open_tabs_ui_delegate.cc',
'sync_driver/open_tabs_ui_delegate.h',
'sync_driver/pref_names.cc',
'sync_driver/pref_names.h',
+ 'sync_driver/profile_sync_auth_provider.cc',
+ 'sync_driver/profile_sync_auth_provider.h',
+ 'sync_driver/protocol_event_observer.cc',
+ 'sync_driver/protocol_event_observer.h',
'sync_driver/proxy_data_type_controller.cc',
'sync_driver/proxy_data_type_controller.h',
+ 'sync_driver/revisit/current_tab_matcher.cc',
+ 'sync_driver/revisit/current_tab_matcher.h',
+ 'sync_driver/revisit/offset_tab_matcher.cc',
+ 'sync_driver/revisit/offset_tab_matcher.h',
+ 'sync_driver/revisit/page_equality.h',
+ 'sync_driver/revisit/page_visit_observer.h',
+ 'sync_driver/revisit/sessions_page_revisit_observer.cc',
+ 'sync_driver/revisit/sessions_page_revisit_observer.h',
+ 'sync_driver/sessions/synced_window_delegates_getter.cc',
+ 'sync_driver/sessions/synced_window_delegates_getter.h',
'sync_driver/shared_change_processor.cc',
'sync_driver/shared_change_processor.h',
'sync_driver/shared_change_processor_ref.cc',
'sync_driver/shared_change_processor_ref.h',
+ 'sync_driver/signin_manager_wrapper.cc',
+ 'sync_driver/signin_manager_wrapper.h',
'sync_driver/sync_api_component_factory.h',
+ 'sync_driver/sync_client.cc',
+ 'sync_driver/sync_client.h',
+ 'sync_driver/sync_driver_switches.cc',
+ 'sync_driver/sync_driver_switches.h',
+ 'sync_driver/sync_error_controller.cc',
+ 'sync_driver/sync_error_controller.h',
'sync_driver/sync_frontend.cc',
'sync_driver/sync_frontend.h',
'sync_driver/sync_prefs.cc',
'sync_driver/sync_prefs.h',
+ 'sync_driver/sync_service.cc',
'sync_driver/sync_service.h',
'sync_driver/sync_service_observer.cc',
'sync_driver/sync_service_observer.h',
+ 'sync_driver/sync_service_utils.cc',
+ 'sync_driver/sync_service_utils.h',
+ 'sync_driver/sync_stopped_reporter.cc',
+ 'sync_driver/sync_stopped_reporter.h',
+ 'sync_driver/sync_util.cc',
+ 'sync_driver/sync_util.h',
'sync_driver/system_encryptor.cc',
'sync_driver/system_encryptor.h',
+ 'sync_driver/tab_node_pool.cc',
+ 'sync_driver/tab_node_pool.h',
'sync_driver/ui_data_type_controller.cc',
'sync_driver/ui_data_type_controller.h',
'sync_driver/user_selectable_sync_type.h',
@@ -91,6 +154,16 @@
'sessions_ios',
],
}],
+ ['configuration_policy==1', {
+ 'dependencies': [
+ 'policy',
+ 'policy_component',
+ ],
+ 'sources': [
+ 'sync_driver/sync_policy_handler.cc',
+ 'sync_driver/sync_policy_handler.h',
+ ],
+ }],
],
},
{
@@ -120,8 +193,12 @@
'sync_driver/fake_data_type_controller.h',
'sync_driver/fake_generic_change_processor.cc',
'sync_driver/fake_generic_change_processor.h',
+ 'sync_driver/fake_sync_client.cc',
+ 'sync_driver/fake_sync_client.h',
'sync_driver/fake_sync_service.cc',
'sync_driver/fake_sync_service.h',
+ 'sync_driver/frontend_data_type_controller_mock.cc',
+ 'sync_driver/frontend_data_type_controller_mock.h',
'sync_driver/local_device_info_provider_mock.cc',
'sync_driver/local_device_info_provider_mock.h',
'sync_driver/model_associator_mock.cc',
diff --git a/chromium/components/syncable_prefs.gypi b/chromium/components/syncable_prefs.gypi
new file mode 100644
index 00000000000..7e143a14e0d
--- /dev/null
+++ b/chromium/components/syncable_prefs.gypi
@@ -0,0 +1,61 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/syncable_prefs
+ 'target_name': 'syncable_prefs',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../base/base.gyp:base_prefs',
+ '../sync/sync.gyp:sync',
+ 'pref_registry',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'syncable_prefs/pref_model_associator.cc',
+ 'syncable_prefs/pref_model_associator.h',
+ 'syncable_prefs/pref_model_associator_client.h',
+ 'syncable_prefs/pref_service_syncable.cc',
+ 'syncable_prefs/pref_service_syncable.h',
+ 'syncable_prefs/pref_service_syncable_factory.cc',
+ 'syncable_prefs/pref_service_syncable_factory.h',
+ 'syncable_prefs/pref_service_syncable_observer.h',
+ 'syncable_prefs/synced_pref_change_registrar.cc',
+ 'syncable_prefs/synced_pref_change_registrar.h',
+ 'syncable_prefs/synced_pref_observer.h',
+ ],
+ 'conditions': [
+ ['configuration_policy==1', {
+ 'dependencies': [
+ 'policy_component_browser',
+ 'policy_component_common',
+ ],
+ }],
+ ],
+ },
+ {
+ # GN version: //components/syncable_prefs:test_support
+ 'target_name': 'syncable_prefs_test_support',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../testing/gtest.gyp:gtest',
+ 'syncable_prefs',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'syncable_prefs/pref_service_mock_factory.cc',
+ 'syncable_prefs/pref_service_mock_factory.h',
+ 'syncable_prefs/testing_pref_service_syncable.cc',
+ 'syncable_prefs/testing_pref_service_syncable.h',
+ ],
+ },
+ ],
+}
diff --git a/chromium/components/test_runner/test_runner.gyp b/chromium/components/test_runner/test_runner.gyp
index 8c9eedf3888..30ffa758b16 100644
--- a/chromium/components/test_runner/test_runner.gyp
+++ b/chromium/components/test_runner/test_runner.gyp
@@ -22,8 +22,10 @@
'../../base/base.gyp:base',
'../../base/base.gyp:base_i18n',
'../../cc/cc.gyp:cc',
+ '../../cc/blink/cc_blink.gyp:cc_blink',
'../../gin/gin.gyp:gin',
'../../gpu/gpu.gyp:gpu',
+ '../../net/net.gyp:net',
'../../skia/skia.gyp:skia',
'../../third_party/WebKit/public/blink.gyp:blink',
'../../ui/events/events.gyp:dom_keycode_converter',
@@ -80,6 +82,8 @@
'spell_check_client.h',
'test_common.cc',
'test_common.h',
+ 'test_info_extractor.cc',
+ 'test_info_extractor.h',
'test_interfaces.cc',
'test_interfaces.h',
'test_plugin.cc',
diff --git a/chromium/components/toolbar.gypi b/chromium/components/toolbar.gypi
new file mode 100644
index 00000000000..77dc03909b4
--- /dev/null
+++ b/chromium/components/toolbar.gypi
@@ -0,0 +1,25 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/toolbar
+ 'target_name': 'toolbar',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../url/url.gyp:url_lib',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'toolbar/toolbar_model.cc',
+ 'toolbar/toolbar_model.h',
+ ],
+ },
+ ],
+}
diff --git a/chromium/components/tracing.gyp b/chromium/components/tracing.gyp
index 7857830c167..8bf23d231c1 100644
--- a/chromium/components/tracing.gyp
+++ b/chromium/components/tracing.gyp
@@ -14,7 +14,7 @@
'targets' : [
{
'target_name': 'tracing',
- 'type': 'static_library',
+ 'type': '<(component)',
'dependencies': [
'../base/base.gyp:base',
'../ipc/ipc.gyp:ipc',
@@ -22,15 +22,21 @@
'include_dirs': [
'..',
],
+ 'defines': [
+ 'TRACING_IMPLEMENTATION=1',
+ ],
'sources': [
'tracing/child_memory_dump_manager_delegate_impl.cc',
'tracing/child_memory_dump_manager_delegate_impl.h',
'tracing/child_trace_message_filter.cc',
'tracing/child_trace_message_filter.h',
- 'tracing/startup_tracing.cc',
- 'tracing/startup_tracing.h',
+ 'tracing/trace_config_file.cc',
+ 'tracing/trace_config_file.h',
+ 'tracing/tracing_export.h',
'tracing/tracing_messages.cc',
'tracing/tracing_messages.h',
+ 'tracing/tracing_switches.cc',
+ 'tracing/tracing_switches.h',
],
},
],
diff --git a/chromium/components/tracing/BUILD.gn b/chromium/components/tracing/BUILD.gn
index 336f5cb5ea4..bd5b2711492 100644
--- a/chromium/components/tracing/BUILD.gn
+++ b/chromium/components/tracing/BUILD.gn
@@ -2,29 +2,51 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-source_set("tracing") {
+component("tracing") {
sources = [
"child_memory_dump_manager_delegate_impl.cc",
"child_memory_dump_manager_delegate_impl.h",
"child_trace_message_filter.cc",
"child_trace_message_filter.h",
+ "tracing_export.h",
"tracing_messages.cc",
"tracing_messages.h",
]
+ defines = [ "TRACING_IMPLEMENTATION" ]
+
deps = [
"//base",
"//ipc",
]
}
-source_set("startup_tracing") {
+component("startup_tracing") {
sources = [
- "startup_tracing.cc",
- "startup_tracing.h",
+ "trace_config_file.cc",
+ "trace_config_file.h",
+ "tracing_export.h",
+ "tracing_switches.cc",
+ "tracing_switches.h",
]
+ defines = [ "TRACING_IMPLEMENTATION" ]
+
deps = [
"//base",
]
}
+
+source_set("unit_tests") {
+ testonly = true
+
+ sources = [
+ "trace_config_file_unittest.cc",
+ ]
+
+ deps = [
+ ":startup_tracing",
+ "//base/test:test_support",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/tracing/DEPS b/chromium/components/tracing/DEPS
index 9634ba4f06a..1c40d981eb6 100644
--- a/chromium/components/tracing/DEPS
+++ b/chromium/components/tracing/DEPS
@@ -1,4 +1,3 @@
include_rules = [
- "+base",
"+ipc",
]
diff --git a/chromium/components/tracing/OWNERS b/chromium/components/tracing/OWNERS
index 2226238acb8..1a389403d36 100644
--- a/chromium/components/tracing/OWNERS
+++ b/chromium/components/tracing/OWNERS
@@ -1,6 +1,7 @@
jbauman@chromium.org
nduca@chromium.org
dsinclair@chromium.org
+simonhatch@chromium.org
# Changes to IPC messages require a security review to avoid introducing
# new sandbox escapes.
diff --git a/chromium/components/tracing/child_memory_dump_manager_delegate_impl.cc b/chromium/components/tracing/child_memory_dump_manager_delegate_impl.cc
index 4e2cc9f318d..fe5c952f6a9 100644
--- a/chromium/components/tracing/child_memory_dump_manager_delegate_impl.cc
+++ b/chromium/components/tracing/child_memory_dump_manager_delegate_impl.cc
@@ -9,67 +9,89 @@
namespace tracing {
+namespace {
+void AbortDumpRequest(const base::trace_event::MemoryDumpRequestArgs& args,
+ const base::trace_event::MemoryDumpCallback& callback) {
+ if (!callback.is_null())
+ callback.Run(args.dump_guid, false /* success */);
+}
+} // namespace
+
// static
ChildMemoryDumpManagerDelegateImpl*
ChildMemoryDumpManagerDelegateImpl::GetInstance() {
- return Singleton<
+ return base::Singleton<
ChildMemoryDumpManagerDelegateImpl,
- LeakySingletonTraits<ChildMemoryDumpManagerDelegateImpl>>::get();
+ base::LeakySingletonTraits<ChildMemoryDumpManagerDelegateImpl>>::get();
}
ChildMemoryDumpManagerDelegateImpl::ChildMemoryDumpManagerDelegateImpl()
- : ctmf_(nullptr) {
- base::trace_event::MemoryDumpManager::GetInstance()->SetDelegate(this);
+ : ctmf_(nullptr),
+ tracing_process_id_(
+ base::trace_event::MemoryDumpManager::kInvalidTracingProcessId) {
}
-ChildMemoryDumpManagerDelegateImpl::~ChildMemoryDumpManagerDelegateImpl() {
-}
+ChildMemoryDumpManagerDelegateImpl::~ChildMemoryDumpManagerDelegateImpl() {}
void ChildMemoryDumpManagerDelegateImpl::SetChildTraceMessageFilter(
ChildTraceMessageFilter* ctmf) {
+ const auto& task_runner = ctmf ? (ctmf->ipc_task_runner()) : nullptr;
// Check that we are either registering the CTMF or tearing it down, but not
// replacing a valid instance with another one (should never happen).
DCHECK(ctmf_ == nullptr || (ctmf == nullptr && ctmf_task_runner_ != nullptr));
ctmf_ = ctmf;
- ctmf_task_runner_ = ctmf ? (ctmf->ipc_task_runner()) : nullptr;
+
+ {
+ base::AutoLock lock(lock_);
+ ctmf_task_runner_ = task_runner;
+ }
+
+ if (ctmf) {
+ base::trace_event::MemoryDumpManager::GetInstance()->Initialize(
+ this /* delegate */, false /* is_coordinator */);
+ }
}
// Invoked in child processes by the MemoryDumpManager.
void ChildMemoryDumpManagerDelegateImpl::RequestGlobalMemoryDump(
const base::trace_event::MemoryDumpRequestArgs& args,
const base::trace_event::MemoryDumpCallback& callback) {
+ // RequestGlobalMemoryDump can be called on any thread, cannot access
+ // ctmf_task_runner_ as it could be racy.
+ scoped_refptr<base::SingleThreadTaskRunner> ctmf_task_runner;
+ {
+ base::AutoLock lock(lock_);
+ ctmf_task_runner = ctmf_task_runner_;
+ }
+
// Bail out if we receive a dump request from the manager before the
// ChildTraceMessageFilter has been initialized.
- if (!ctmf_task_runner_) {
- if (!callback.is_null())
- callback.Run(args.dump_guid, false /* success */);
- return;
- }
+ if (!ctmf_task_runner)
+ return AbortDumpRequest(args, callback);
// Make sure we access |ctmf_| only on the thread where it lives to avoid
// races on shutdown.
- if (!ctmf_task_runner_->BelongsToCurrentThread()) {
- ctmf_task_runner_->PostTask(
+ if (!ctmf_task_runner->BelongsToCurrentThread()) {
+ const bool did_post_task = ctmf_task_runner->PostTask(
FROM_HERE,
base::Bind(&ChildMemoryDumpManagerDelegateImpl::RequestGlobalMemoryDump,
base::Unretained(this), args, callback));
+ if (!did_post_task)
+ return AbortDumpRequest(args, callback);
return;
}
// The ChildTraceMessageFilter could have been destroyed while hopping on the
// right thread. If this is the case, bail out.
- if (!ctmf_) {
- if (!callback.is_null())
- callback.Run(args.dump_guid, false /* success */);
- return;
- }
+ if (!ctmf_)
+ return AbortDumpRequest(args, callback);
// Send the request up to the browser process' MessageDumpmanager.
ctmf_->SendGlobalMemoryDumpRequest(args, callback);
}
-bool ChildMemoryDumpManagerDelegateImpl::IsCoordinatorProcess() const {
- return false;
+uint64 ChildMemoryDumpManagerDelegateImpl::GetTracingProcessId() const {
+ return tracing_process_id_;
}
} // namespace tracing
diff --git a/chromium/components/tracing/child_memory_dump_manager_delegate_impl.h b/chromium/components/tracing/child_memory_dump_manager_delegate_impl.h
index 912815dd018..ca5de293ed7 100644
--- a/chromium/components/tracing/child_memory_dump_manager_delegate_impl.h
+++ b/chromium/components/tracing/child_memory_dump_manager_delegate_impl.h
@@ -9,6 +9,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
+#include "base/synchronization/lock.h"
namespace base {
class SingleThreadTaskRunner;
@@ -33,16 +34,27 @@ class ChildMemoryDumpManagerDelegateImpl
void RequestGlobalMemoryDump(
const base::trace_event::MemoryDumpRequestArgs& args,
const base::trace_event::MemoryDumpCallback& callback) override;
- bool IsCoordinatorProcess() const override;
+ uint64 GetTracingProcessId() const override;
void SetChildTraceMessageFilter(ChildTraceMessageFilter* ctmf);
+ // Pass kInvalidTracingProcessId to invalidate the id.
+ void set_tracing_process_id(uint64 id) {
+ DCHECK_IMPLIES(
+ tracing_process_id_ !=
+ base::trace_event::MemoryDumpManager::kInvalidTracingProcessId,
+ id == base::trace_event::MemoryDumpManager::kInvalidTracingProcessId ||
+ id == tracing_process_id_);
+ tracing_process_id_ = id;
+ }
+
protected:
// Make CreateProcessDump() visible to ChildTraceMessageFilter.
friend class ChildTraceMessageFilter;
private:
- friend struct DefaultSingletonTraits<ChildMemoryDumpManagerDelegateImpl>;
+ friend struct base::DefaultSingletonTraits<
+ ChildMemoryDumpManagerDelegateImpl>;
ChildMemoryDumpManagerDelegateImpl();
~ChildMemoryDumpManagerDelegateImpl() override;
@@ -53,6 +65,14 @@ class ChildMemoryDumpManagerDelegateImpl
// It is NULL iff |cmtf_| is NULL.
scoped_refptr<base::SingleThreadTaskRunner> ctmf_task_runner_;
+ // Protects from concurrent access to |ctmf_task_runner_| to allow
+ // RequestGlobalMemoryDump to be called from arbitrary threads.
+ base::Lock lock_;
+
+ // The unique id of the child process, created for tracing and is expected to
+ // be valid only when tracing is enabled.
+ uint64 tracing_process_id_;
+
DISALLOW_COPY_AND_ASSIGN(ChildMemoryDumpManagerDelegateImpl);
};
diff --git a/chromium/components/tracing/child_trace_message_filter.cc b/chromium/components/tracing/child_trace_message_filter.cc
index 19fef02e106..62e13aec2c0 100644
--- a/chromium/components/tracing/child_trace_message_filter.cc
+++ b/chromium/components/tracing/child_trace_message_filter.cc
@@ -4,6 +4,7 @@
#include "components/tracing/child_trace_message_filter.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/trace_event/trace_event.h"
#include "components/tracing/child_memory_dump_manager_delegate_impl.h"
#include "components/tracing/tracing_messages.h"
@@ -13,6 +14,12 @@ using base::trace_event::TraceLog;
namespace tracing {
+namespace {
+
+const int kMinTimeBetweenHistogramChangesInSeconds = 10;
+
+} // namespace
+
ChildTraceMessageFilter::ChildTraceMessageFilter(
base::SingleThreadTaskRunner* ipc_task_runner)
: sender_(NULL),
@@ -50,6 +57,8 @@ bool ChildTraceMessageFilter::OnMessageReceived(const IPC::Message& message) {
OnProcessMemoryDumpRequest)
IPC_MESSAGE_HANDLER(TracingMsg_GlobalMemoryDumpResponse,
OnGlobalMemoryDumpResponse)
+ IPC_MESSAGE_HANDLER(TracingMsg_SetUMACallback, OnSetUMACallback)
+ IPC_MESSAGE_HANDLER(TracingMsg_ClearUMACallback, OnClearUMACallback)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -226,4 +235,80 @@ void ChildTraceMessageFilter::OnGlobalMemoryDumpResponse(uint64 dump_guid,
pending_memory_dump_callback_.Run(dump_guid, success);
}
+void ChildTraceMessageFilter::OnHistogramChanged(
+ const std::string& histogram_name,
+ base::Histogram::Sample reference_lower_value,
+ base::Histogram::Sample reference_upper_value,
+ base::Histogram::Sample actual_value) {
+ if (actual_value < reference_lower_value ||
+ actual_value > reference_upper_value)
+ return;
+
+ ipc_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&ChildTraceMessageFilter::SendTriggerMessage, this,
+ histogram_name));
+}
+
+void ChildTraceMessageFilter::SendTriggerMessage(
+ const std::string& histogram_name) {
+ if (!histogram_last_changed_.is_null()) {
+ base::Time computed_next_allowed_time =
+ histogram_last_changed_ +
+ base::TimeDelta::FromSeconds(kMinTimeBetweenHistogramChangesInSeconds);
+ if (computed_next_allowed_time > base::Time::Now())
+ return;
+ }
+ histogram_last_changed_ = base::Time::Now();
+
+ if (sender_)
+ sender_->Send(new TracingHostMsg_TriggerBackgroundTrace(histogram_name));
+}
+
+void ChildTraceMessageFilter::OnSetUMACallback(
+ const std::string& histogram_name,
+ int histogram_lower_value,
+ int histogram_upper_value) {
+ histogram_last_changed_ = base::Time();
+ base::StatisticsRecorder::SetCallback(
+ histogram_name,
+ base::Bind(&ChildTraceMessageFilter::OnHistogramChanged, this,
+ histogram_name, histogram_lower_value, histogram_upper_value));
+
+ base::HistogramBase* existing_histogram =
+ base::StatisticsRecorder::FindHistogram(histogram_name);
+ if (!existing_histogram)
+ return;
+
+ scoped_ptr<base::HistogramSamples> samples =
+ existing_histogram->SnapshotSamples();
+ if (!samples)
+ return;
+
+ scoped_ptr<base::SampleCountIterator> sample_iterator = samples->Iterator();
+ if (!sample_iterator)
+ return;
+
+ while (!sample_iterator->Done()) {
+ base::HistogramBase::Sample min;
+ base::HistogramBase::Sample max;
+ base::HistogramBase::Count count;
+ sample_iterator->Get(&min, &max, &count);
+ if (min >= histogram_lower_value && max <= histogram_upper_value &&
+ count > 0) {
+ ipc_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&ChildTraceMessageFilter::SendTriggerMessage,
+ this, histogram_name));
+ break;
+ }
+
+ sample_iterator->Next();
+ }
+}
+
+void ChildTraceMessageFilter::OnClearUMACallback(
+ const std::string& histogram_name) {
+ histogram_last_changed_ = base::Time();
+ base::StatisticsRecorder::ClearCallback(histogram_name);
+}
+
} // namespace tracing
diff --git a/chromium/components/tracing/child_trace_message_filter.h b/chromium/components/tracing/child_trace_message_filter.h
index f61e29429e2..124f5625f3b 100644
--- a/chromium/components/tracing/child_trace_message_filter.h
+++ b/chromium/components/tracing/child_trace_message_filter.h
@@ -7,7 +7,10 @@
#include "base/bind.h"
#include "base/memory/ref_counted_memory.h"
+#include "base/metrics/histogram.h"
+#include "base/time/time.h"
#include "base/trace_event/memory_dump_request_args.h"
+#include "components/tracing/tracing_export.h"
#include "ipc/message_filter.h"
namespace base {
@@ -17,7 +20,7 @@ class SingleThreadTaskRunner;
namespace tracing {
// This class sends and receives trace messages on child processes.
-class ChildTraceMessageFilter : public IPC::MessageFilter {
+class TRACING_EXPORT ChildTraceMessageFilter : public IPC::MessageFilter {
public:
explicit ChildTraceMessageFilter(
base::SingleThreadTaskRunner* ipc_task_runner);
@@ -57,6 +60,15 @@ class ChildTraceMessageFilter : public IPC::MessageFilter {
void OnProcessMemoryDumpRequest(
const base::trace_event::MemoryDumpRequestArgs& args);
void OnGlobalMemoryDumpResponse(uint64 dump_guid, bool success);
+ void OnSetUMACallback(const std::string& histogram_name,
+ int histogram_lower_value,
+ int histogram_upper_value);
+ void OnClearUMACallback(const std::string& histogram_name);
+ void OnHistogramChanged(const std::string& histogram_name,
+ base::Histogram::Sample reference_lower_value,
+ base::Histogram::Sample reference_upper_value,
+ base::Histogram::Sample actual_value);
+ void SendTriggerMessage(const std::string& histogram_name);
// Callback from trace subsystem.
void OnTraceDataCollected(
@@ -79,6 +91,8 @@ class ChildTraceMessageFilter : public IPC::MessageFilter {
// callback of the outstanding memory dump request, if any.
base::trace_event::MemoryDumpCallback pending_memory_dump_callback_;
+ base::Time histogram_last_changed_;
+
DISALLOW_COPY_AND_ASSIGN(ChildTraceMessageFilter);
};
diff --git a/chromium/components/tracing/startup_tracing.cc b/chromium/components/tracing/startup_tracing.cc
deleted file mode 100644
index 321b95092a4..00000000000
--- a/chromium/components/tracing/startup_tracing.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 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/tracing/startup_tracing.h"
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/path_service.h"
-#include "base/trace_event/trace_event.h"
-
-namespace tracing {
-
-namespace {
-
-// Maximum trace config file size that will be loaded, in bytes.
-const size_t kTraceConfigFileSizeLimit = 64 * 1024;
-
-// Trace config file path:
-// - Android: /data/local/.config/chrome-trace-config.json
-// - POSIX other than Android: $HOME/.config/chrome-trace-config.json
-// - Win: %USERPROFILE%/.config/chrome-trace-config.json
-#if defined(OS_ANDROID)
-const base::FilePath::CharType kAndroidTraceConfigDir[] =
- FILE_PATH_LITERAL("/data/local");
-#endif
-
-const base::FilePath::CharType kChromeConfigDir[] =
- FILE_PATH_LITERAL(".config");
-const base::FilePath::CharType kTraceConfigFileName[] =
- FILE_PATH_LITERAL("chrome-trace-config.json");
-
-base::FilePath GetTraceConfigFilePath() {
-#if defined(OS_ANDROID)
- base::FilePath path(kAndroidTraceConfigDir);
-#elif defined(OS_POSIX) || defined(OS_WIN)
- base::FilePath path;
- PathService::Get(base::DIR_HOME, &path);
-#else
- base::FilePath path;
-#endif
- path = path.Append(kChromeConfigDir);
- path = path.Append(kTraceConfigFileName);
- return path;
-}
-
-} // namespace
-
-void EnableStartupTracingIfConfigFileExists() {
- base::FilePath trace_config_file_path = GetTraceConfigFilePath();
- if (!base::PathExists(trace_config_file_path))
- return;
-
- std::string trace_config_str;
- if (!base::ReadFileToString(trace_config_file_path,
- &trace_config_str,
- kTraceConfigFileSizeLimit)) {
- return;
- }
-
- base::trace_event::TraceConfig trace_config(trace_config_str);
- base::trace_event::TraceLog::GetInstance()->SetEnabled(
- trace_config, base::trace_event::TraceLog::RECORDING_MODE);
-}
-
-} // namespace tracing
diff --git a/chromium/components/tracing/startup_tracing.h b/chromium/components/tracing/startup_tracing.h
deleted file mode 100644
index ae68f6fa654..00000000000
--- a/chromium/components/tracing/startup_tracing.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 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_TRACING_STARTUP_TRACING_H_
-#define COMPONENTS_TRACING_STARTUP_TRACING_H_
-
-namespace tracing {
-
-// Enable startup tracing according to the trace config file. If the trace
-// config file does not exist, it will do nothing. This is designed to be used
-// by Telemetry. Telemetry will stop tracing via DevTools later. To avoid
-// conflict, this should not be used when --trace-startup is enabled.
-void EnableStartupTracingIfConfigFileExists();
-
-} // namespace tracing
-
-#endif // COMPONENTS_TRACING_STARTUP_TRACING_H_
diff --git a/chromium/components/tracing/trace_config_file.cc b/chromium/components/tracing/trace_config_file.cc
new file mode 100644
index 00000000000..769d527ca8b
--- /dev/null
+++ b/chromium/components/tracing/trace_config_file.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 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/tracing/trace_config_file.h"
+
+#include <string>
+
+#include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "base/values.h"
+#include "components/tracing/tracing_switches.h"
+
+namespace tracing {
+
+namespace {
+
+// Maximum trace config file size that will be loaded, in bytes.
+const size_t kTraceConfigFileSizeLimit = 64 * 1024;
+
+// Trace config file path:
+// - Android: /data/local/chrome-trace-config.json
+// - Others: specified by --trace-config-file flag.
+#if defined(OS_ANDROID)
+const base::FilePath::CharType kAndroidTraceConfigFile[] =
+ FILE_PATH_LITERAL("/data/local/chrome-trace-config.json");
+#endif
+
+const base::FilePath::CharType kDefaultResultFile[] =
+ FILE_PATH_LITERAL("chrometrace.log");
+
+// String parameters that can be used to parse the trace config file content.
+const char kTraceConfigParam[] = "trace_config";
+const char kStartupDurationParam[] = "startup_duration";
+const char kResultFileParam[] = "result_file";
+
+} // namespace
+
+TraceConfigFile* TraceConfigFile::GetInstance() {
+ return base::Singleton<TraceConfigFile,
+ base::DefaultSingletonTraits<TraceConfigFile>>::get();
+}
+
+TraceConfigFile::TraceConfigFile()
+ : is_enabled_(false),
+ trace_config_(base::trace_event::TraceConfig()),
+ startup_duration_(0),
+ result_file_(kDefaultResultFile) {
+#if defined(OS_ANDROID)
+ base::FilePath trace_config_file(kAndroidTraceConfigFile);
+#else
+ const base::CommandLine& command_line =
+ *base::CommandLine::ForCurrentProcess();
+ if (!command_line.HasSwitch(switches::kTraceConfigFile) ||
+ command_line.HasSwitch(switches::kTraceStartup) ||
+ command_line.HasSwitch(switches::kTraceShutdown)) {
+ return;
+ }
+ base::FilePath trace_config_file =
+ command_line.GetSwitchValuePath(switches::kTraceConfigFile);
+#endif
+
+ if (trace_config_file.empty()) {
+ // If the trace config file path is not specified, trace Chrome with the
+ // default configuration for 5 sec.
+ startup_duration_ = 5;
+ is_enabled_ = true;
+ return;
+ }
+
+ if (!base::PathExists(trace_config_file))
+ return;
+
+ std::string trace_config_file_content;
+ if (!base::ReadFileToString(trace_config_file,
+ &trace_config_file_content,
+ kTraceConfigFileSizeLimit)) {
+ return;
+ }
+ is_enabled_ = ParseTraceConfigFileContent(trace_config_file_content);
+}
+
+TraceConfigFile::~TraceConfigFile() {
+}
+
+bool TraceConfigFile::ParseTraceConfigFileContent(const std::string& content) {
+ scoped_ptr<base::Value> value(base::JSONReader::Read(content));
+ if (!value || !value->IsType(base::Value::TYPE_DICTIONARY))
+ return false;
+
+ scoped_ptr<base::DictionaryValue> dict(
+ static_cast<base::DictionaryValue*>(value.release()));
+
+ base::DictionaryValue* trace_config_dict = NULL;
+ if (!dict->GetDictionary(kTraceConfigParam, &trace_config_dict))
+ return false;
+
+ std::string trace_config_str;
+ base::JSONWriter::Write(*trace_config_dict, &trace_config_str);
+ trace_config_ = base::trace_event::TraceConfig(trace_config_str);
+
+ if (!dict->GetInteger(kStartupDurationParam, &startup_duration_))
+ startup_duration_ = 0;
+
+ if (startup_duration_ < 0)
+ startup_duration_ = 0;
+
+ std::string result_file_str;
+ if (dict->GetString(kResultFileParam, &result_file_str))
+ result_file_ = base::FilePath().AppendASCII(result_file_str);
+
+ return true;
+}
+
+bool TraceConfigFile::IsEnabled() const {
+ return is_enabled_;
+}
+
+base::trace_event::TraceConfig TraceConfigFile::GetTraceConfig() const {
+ DCHECK(IsEnabled());
+ return trace_config_;
+}
+
+int TraceConfigFile::GetStartupDuration() const {
+ DCHECK(IsEnabled());
+ return startup_duration_;
+}
+
+#if !defined(OS_ANDROID)
+base::FilePath TraceConfigFile::GetResultFile() const {
+ DCHECK(IsEnabled());
+ return result_file_;
+}
+#endif
+
+} // namespace tracing
diff --git a/chromium/components/tracing/trace_config_file.h b/chromium/components/tracing/trace_config_file.h
new file mode 100644
index 00000000000..863fee49b5b
--- /dev/null
+++ b/chromium/components/tracing/trace_config_file.h
@@ -0,0 +1,96 @@
+// Copyright (c) 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_TRACING_TRACE_CONFIG_FILE_H_
+#define COMPONENTS_TRACING_TRACE_CONFIG_FILE_H_
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/trace_event/trace_config.h"
+#include "components/tracing/tracing_export.h"
+
+namespace base {
+template <typename Type> struct DefaultSingletonTraits;
+} // namespace base
+
+namespace tracing {
+
+// TraceConfigFile is a singleton that contains the configurations of tracing.
+// One can create a trace config file and use it to configure startup and/or
+// shutdown tracing.
+//
+// The trace config file should be JSON formated. One example is:
+// {
+// "trace_config": {
+// "record_mode": "record-until-full",
+// "included_categories": ["cc", "skia"]
+// },
+// "startup_duration": 5,
+// "result_file": "chrometrace.log"
+// }
+//
+// trace_config: The configuration of tracing. Please see the details in
+// base/trace_event/trace_config.h.
+//
+// startup_duration: The duration for startup tracing in terms of seconds.
+// Tracing will stop automatically after the duration. If this
+// value is not specified, the duration is 0 and one needs
+// to stop tracing by other ways, e.g., by DevTools, or get
+// the result file after shutting the browser down.
+//
+// result_file: The file that contains the trace log. The default result
+// file path is chrometrace.log. Chrome will dump the trace
+// log to this file
+// 1) after startup_duration if it is specified;
+// 2) or after browser shutdown if startup duration is 0.
+// One can also stop tracing and get the result by other ways,
+// e.g., by DevTools. In that case, the trace log will not be
+// saved to this file.
+// Notice: This is not supported on Android. The result file
+// path will be generated by tracing controller.
+//
+// The trace config file can be specified by the --trace-config-file flag on
+// most platforms except on Android, e.g., --trace-config-file=path/to/file/.
+// This flag should not be used with --trace-startup or --trace-shutdown. If
+// those two flags are used, --trace-config-file flag will be ignored. If the
+// --trace-config-file flag is used without the file path, Chrome will do
+// startup tracing with 5 seconds' startup duration.
+//
+// On Android, Chrome does not read the --trace-config-file flag, because not
+// all Chrome based browsers read customized flag, e.g., Android WebView. Chrome
+// on Android reads from a fixed file location:
+// /data/local/chrome-trace-config.json
+// If this file exists, Chrome will start tracing according to the configuration
+// specified in the file, otherwise, Chrome will not start tracing.
+class TRACING_EXPORT TraceConfigFile {
+ public:
+ static TraceConfigFile* GetInstance();
+
+ bool IsEnabled() const;
+ base::trace_event::TraceConfig GetTraceConfig() const;
+ int GetStartupDuration() const;
+#if !defined(OS_ANDROID)
+ base::FilePath GetResultFile() const;
+#endif
+
+ private:
+ // This allows constructor and destructor to be private and usable only
+ // by the Singleton class.
+ friend struct base::DefaultSingletonTraits<TraceConfigFile>;
+ TraceConfigFile();
+ ~TraceConfigFile();
+
+ bool ParseTraceConfigFileContent(const std::string& content);
+
+ bool is_enabled_;
+ base::trace_event::TraceConfig trace_config_;
+ int startup_duration_;
+ base::FilePath result_file_;
+
+ DISALLOW_COPY_AND_ASSIGN(TraceConfigFile);
+};
+
+} // namespace tracing
+
+#endif // COMPONENTS_TRACING_TRACE_CONFIG_FILE_H_
diff --git a/chromium/components/tracing/trace_config_file_unittest.cc b/chromium/components/tracing/trace_config_file_unittest.cc
new file mode 100644
index 00000000000..d62c4d44217
--- /dev/null
+++ b/chromium/components/tracing/trace_config_file_unittest.cc
@@ -0,0 +1,220 @@
+// Copyright (c) 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 "base/at_exit.h"
+#include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "components/tracing/trace_config_file.h"
+#include "components/tracing/tracing_switches.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace tracing {
+
+namespace {
+
+const char kTraceConfig[] =
+ "{"
+ "\"enable_argument_filter\":true,"
+ "\"enable_sampling\":true,"
+ "\"enable_systrace\":true,"
+ "\"excluded_categories\":[\"excluded\",\"exc_pattern*\"],"
+ "\"included_categories\":[\"included\","
+ "\"inc_pattern*\","
+ "\"disabled-by-default-cc\"],"
+ "\"record_mode\":\"record-continuously\","
+ "\"synthetic_delays\":[\"test.Delay1;16\",\"test.Delay2;32\"]"
+ "}";
+
+std::string GetTraceConfigFileContent(std::string trace_config,
+ std::string startup_duration,
+ std::string result_file) {
+ std::string content = "{";
+ if (!trace_config.empty())
+ content += "\"trace_config\":" + trace_config;
+
+ if (!startup_duration.empty()) {
+ if (content != "{")
+ content += ",";
+ content += "\"startup_duration\":" + startup_duration;
+ }
+
+ if (!result_file.empty()) {
+ if (content != "{")
+ content += ",";
+ content += "\"result_file\":\"" + result_file + "\"";
+ }
+
+ content += "}";
+ return content;
+}
+
+} // namespace
+
+TEST(TraceConfigFileTest, TraceStartupEnabled) {
+ base::ShadowingAtExitManager sem;
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kTraceStartup);
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kTraceConfigFile);
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, TraceShutdownEnabled) {
+ base::ShadowingAtExitManager sem;
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kTraceShutdown);
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kTraceConfigFile);
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, TraceConfigFileNotEnabled) {
+ base::ShadowingAtExitManager sem;
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, TraceConfigFileEnabledWithoutPath) {
+ base::ShadowingAtExitManager sem;
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kTraceConfigFile);
+
+ ASSERT_TRUE(TraceConfigFile::GetInstance()->IsEnabled());
+ EXPECT_EQ(base::trace_event::TraceConfig().ToString(),
+ TraceConfigFile::GetInstance()->GetTraceConfig().ToString());
+ EXPECT_EQ(5, TraceConfigFile::GetInstance()->GetStartupDuration());
+ EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("chrometrace.log")),
+ TraceConfigFile::GetInstance()->GetResultFile());
+}
+
+TEST(TraceConfigFileTest, TraceConfigFileEnabledWithInvalidPath) {
+ base::ShadowingAtExitManager sem;
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile,
+ base::FilePath(FILE_PATH_LITERAL("invalid-trace-config-file-path")));
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, ValidContent) {
+ base::ShadowingAtExitManager sem;
+ std::string content = GetTraceConfigFileContent(
+ kTraceConfig, "10", "trace_result_file.log");
+
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ ASSERT_NE(-1, base::WriteFile(
+ trace_config_file, content.c_str(), (int)content.length()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ ASSERT_TRUE(TraceConfigFile::GetInstance()->IsEnabled());
+ EXPECT_STREQ(
+ kTraceConfig,
+ TraceConfigFile::GetInstance()->GetTraceConfig().ToString().c_str());
+ EXPECT_EQ(10, TraceConfigFile::GetInstance()->GetStartupDuration());
+ EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("trace_result_file.log")),
+ TraceConfigFile::GetInstance()->GetResultFile());
+}
+
+TEST(TraceConfigFileTest, ValidContentWithOnlyTraceConfig) {
+ base::ShadowingAtExitManager sem;
+ std::string content = GetTraceConfigFileContent(kTraceConfig, "", "");
+
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ ASSERT_NE(-1, base::WriteFile(
+ trace_config_file, content.c_str(), (int)content.length()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ ASSERT_TRUE(TraceConfigFile::GetInstance()->IsEnabled());
+ EXPECT_STREQ(
+ kTraceConfig,
+ TraceConfigFile::GetInstance()->GetTraceConfig().ToString().c_str());
+ EXPECT_EQ(0, TraceConfigFile::GetInstance()->GetStartupDuration());
+ EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("chrometrace.log")),
+ TraceConfigFile::GetInstance()->GetResultFile());
+}
+
+TEST(TraceConfigFileTest, ContentWithNegtiveDuration) {
+ base::ShadowingAtExitManager sem;
+ std::string content = GetTraceConfigFileContent(kTraceConfig, "-1", "");
+
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ ASSERT_NE(-1, base::WriteFile(
+ trace_config_file, content.c_str(), (int)content.length()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ ASSERT_TRUE(TraceConfigFile::GetInstance()->IsEnabled());
+ EXPECT_STREQ(
+ kTraceConfig,
+ TraceConfigFile::GetInstance()->GetTraceConfig().ToString().c_str());
+ EXPECT_EQ(0, TraceConfigFile::GetInstance()->GetStartupDuration());
+ EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("chrometrace.log")),
+ TraceConfigFile::GetInstance()->GetResultFile());
+}
+
+TEST(TraceConfigFileTest, ContentWithoutTraceConfig) {
+ base::ShadowingAtExitManager sem;
+ std::string content = GetTraceConfigFileContent(
+ "", "10", "trace_result_file.log");
+
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ ASSERT_NE(-1, base::WriteFile(
+ trace_config_file, content.c_str(), (int)content.length()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, InvalidContent) {
+ base::ShadowingAtExitManager sem;
+ std::string content = "invalid trace config file content";
+
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ ASSERT_NE(-1, base::WriteFile(
+ trace_config_file, content.c_str(), (int)content.length()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, EmptyContent) {
+ base::ShadowingAtExitManager sem;
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+} // namespace tracing
diff --git a/chromium/components/tracing/tracing_export.h b/chromium/components/tracing/tracing_export.h
new file mode 100644
index 00000000000..ac24e303bcd
--- /dev/null
+++ b/chromium/components/tracing/tracing_export.h
@@ -0,0 +1,29 @@
+// 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_TRACING_TRACING_EXPORT_H_
+#define COMPONENTS_TRACING_TRACING_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(TRACING_IMPLEMENTATION)
+#define TRACING_EXPORT __declspec(dllexport)
+#else
+#define TRACING_EXPORT __declspec(dllimport)
+#endif // defined(TRACING_IMPLEMENTATION)
+
+#else // defined(WIN32)
+#if defined(TRACING_IMPLEMENTATION)
+#define TRACING_EXPORT __attribute__((visibility("default")))
+#else
+#define TRACING_EXPORT
+#endif // defined(TRACING_IMPLEMENTATION)
+#endif
+
+#else // defined(COMPONENT_BUILD)
+#define TRACING_EXPORT
+#endif
+
+#endif // COMPONENTS_TRACING_TRACING_EXPORT_H_
diff --git a/chromium/components/tracing/tracing_messages.h b/chromium/components/tracing/tracing_messages.h
index 88c7834064b..cd5a2020dda 100644
--- a/chromium/components/tracing/tracing_messages.h
+++ b/chromium/components/tracing/tracing_messages.h
@@ -7,14 +7,18 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/metrics/histogram.h"
#include "base/sync_socket.h"
#include "base/trace_event/memory_dump_request_args.h"
#include "base/trace_event/trace_event_impl.h"
+#include "components/tracing/tracing_export.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_utils.h"
#include "ipc/ipc_platform_file.h"
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT TRACING_EXPORT
#define IPC_MESSAGE_START TracingMsgStart
IPC_STRUCT_TRAITS_BEGIN(base::trace_event::TraceLogStatus)
@@ -25,8 +29,16 @@ IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(base::trace_event::MemoryDumpRequestArgs)
IPC_STRUCT_TRAITS_MEMBER(dump_guid)
IPC_STRUCT_TRAITS_MEMBER(dump_type)
+IPC_STRUCT_TRAITS_MEMBER(level_of_detail)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(base::trace_event::MemoryDumpArgs)
+ IPC_STRUCT_TRAITS_MEMBER(level_of_detail)
+IPC_STRUCT_TRAITS_END()
+
+IPC_ENUM_TRAITS_MAX_VALUE(base::trace_event::MemoryDumpLevelOfDetail,
+ base::trace_event::MemoryDumpLevelOfDetail::LAST)
+
IPC_ENUM_TRAITS_MAX_VALUE(
base::trace_event::MemoryDumpType,
static_cast<int>(base::trace_event::MemoryDumpType::LAST))
@@ -75,6 +87,14 @@ IPC_MESSAGE_CONTROL2(TracingMsg_GlobalMemoryDumpResponse,
uint64 /* dump_guid */,
bool /* success */)
+IPC_MESSAGE_CONTROL3(TracingMsg_SetUMACallback,
+ std::string /* histogram_name */,
+ base::HistogramBase::Sample /* histogram_lower_value */,
+ base::HistogramBase::Sample /* histogram_uppwer_value */)
+
+IPC_MESSAGE_CONTROL1(TracingMsg_ClearUMACallback,
+ std::string /* histogram_name */)
+
// Sent everytime when a watch event is matched.
IPC_MESSAGE_CONTROL0(TracingHostMsg_WatchEventMatched)
@@ -110,3 +130,6 @@ IPC_MESSAGE_CONTROL1(TracingHostMsg_GlobalMemoryDumpRequest,
IPC_MESSAGE_CONTROL2(TracingHostMsg_ProcessMemoryDumpResponse,
uint64 /* dump_guid */,
bool /* success */)
+
+IPC_MESSAGE_CONTROL1(TracingHostMsg_TriggerBackgroundTrace,
+ std::string /* name */)
diff --git a/chromium/components/tracing/tracing_switches.cc b/chromium/components/tracing/tracing_switches.cc
new file mode 100644
index 00000000000..ba3c1b158fb
--- /dev/null
+++ b/chromium/components/tracing/tracing_switches.cc
@@ -0,0 +1,52 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/tracing/tracing_switches.h"
+
+namespace switches {
+
+// Causes TRACE_EVENT flags to be recorded from startup.
+// This flag will be ignored if --trace-startup or --trace-shutdown is provided.
+const char kTraceConfigFile[] = "trace-config-file";
+
+// Causes TRACE_EVENT flags to be recorded beginning with shutdown. Optionally,
+// can specify the specific trace categories to include (e.g.
+// --trace-shutdown=base,net) otherwise, all events are recorded.
+// --trace-shutdown-file can be used to control where the trace log gets stored
+// to since there is otherwise no way to access the result.
+const char kTraceShutdown[] = "trace-shutdown";
+
+// If supplied, sets the file which shutdown tracing will be stored into, if
+// omitted the default will be used "chrometrace.log" in the current directory.
+// Has no effect unless --trace-shutdown is also supplied.
+// Example: --trace-shutdown --trace-shutdown-file=/tmp/trace_event.log
+const char kTraceShutdownFile[] = "trace-shutdown-file";
+
+// Causes TRACE_EVENT flags to be recorded from startup. Optionally, can
+// specify the specific trace categories to include (e.g.
+// --trace-startup=base,net) otherwise, all events are recorded. Setting this
+// flag results in the first call to BeginTracing() to receive all trace events
+// since startup. In Chrome, you may find --trace-startup-file and
+// --trace-startup-duration to control the auto-saving of the trace (not
+// supported in the base-only TraceLog component).
+const char kTraceStartup[] = "trace-startup";
+
+// Sets the time in seconds until startup tracing ends. If omitted a default of
+// 5 seconds is used. Has no effect without --trace-startup, or if
+// --startup-trace-file=none was supplied.
+const char kTraceStartupDuration[] = "trace-startup-duration";
+
+// If supplied, sets the file which startup tracing will be stored into, if
+// omitted the default will be used "chrometrace.log" in the current directory.
+// Has no effect unless --trace-startup is also supplied.
+// Example: --trace-startup --trace-startup-file=/tmp/trace_event.log
+// As a special case, can be set to 'none' - this disables automatically saving
+// the result to a file and the first manually recorded trace will then receive
+// all events since startup.
+const char kTraceStartupFile[] = "trace-startup-file";
+
+// Sets the target URL for uploading tracing data.
+const char kTraceUploadURL[] = "trace-upload-url";
+
+} // namespace switches
diff --git a/chromium/components/tracing/tracing_switches.h b/chromium/components/tracing/tracing_switches.h
new file mode 100644
index 00000000000..263a49bcf5c
--- /dev/null
+++ b/chromium/components/tracing/tracing_switches.h
@@ -0,0 +1,22 @@
+// 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_TRACING_TRACING_SWITCHES_H_
+#define COMPONENTS_TRACING_TRACING_SWITCHES_H_
+
+#include "components/tracing/tracing_export.h"
+
+namespace switches {
+
+TRACING_EXPORT extern const char kTraceConfigFile[];
+TRACING_EXPORT extern const char kTraceShutdown[];
+TRACING_EXPORT extern const char kTraceShutdownFile[];
+TRACING_EXPORT extern const char kTraceStartup[];
+TRACING_EXPORT extern const char kTraceStartupDuration[];
+TRACING_EXPORT extern const char kTraceStartupFile[];
+TRACING_EXPORT extern const char kTraceUploadURL[];
+
+} // namespace switches
+
+#endif // COMPONENTS_TRACING_TRACING_SWITCHES_H_
diff --git a/chromium/components/tracing_nacl.gyp b/chromium/components/tracing_nacl.gyp
index 19cae0b6de6..1260e852e69 100644
--- a/chromium/components/tracing_nacl.gyp
+++ b/chromium/components/tracing_nacl.gyp
@@ -37,10 +37,13 @@
'tracing/child_memory_dump_manager_delegate_impl.h',
'tracing/child_trace_message_filter.cc',
'tracing/child_trace_message_filter.h',
- 'tracing/startup_tracing.cc',
- 'tracing/startup_tracing.h',
+ 'tracing/trace_config_file.cc',
+ 'tracing/trace_config_file.h',
+ 'tracing/tracing_export.h',
'tracing/tracing_messages.cc',
'tracing/tracing_messages.h',
+ 'tracing/tracing_switches.cc',
+ 'tracing/tracing_switches.h',
],
},
],
diff --git a/chromium/components/translate.gypi b/chromium/components/translate.gypi
index c003e3ebb91..f550365cb18 100644
--- a/chromium/components/translate.gypi
+++ b/chromium/components/translate.gypi
@@ -17,6 +17,7 @@
'../url/url.gyp:url_lib',
'components_resources.gyp:components_resources',
'components_strings.gyp:components_strings',
+ 'data_use_measurement_core',
'infobars_core',
'language_usage_metrics',
'pref_registry',
@@ -113,7 +114,7 @@
'<(DEPTH)/third_party/cld/cld.gyp:cld',
],
}],
- ['cld_version==0 or cld_version==2', {
+ ['cld_version==2', {
'dependencies': [
'<(DEPTH)/third_party/cld_2/cld_2.gyp:cld_2',
],
@@ -195,8 +196,6 @@
],
'sources': [
# Note: sources list duplicated in GN build.
- 'translate/content/renderer/data_file_renderer_cld_data_provider.cc',
- 'translate/content/renderer/data_file_renderer_cld_data_provider.h',
'translate/content/renderer/renderer_cld_data_provider.cc',
'translate/content/renderer/renderer_cld_data_provider.h',
'translate/content/renderer/renderer_cld_data_provider_factory.cc',
@@ -207,10 +206,14 @@
'translate/content/renderer/translate_helper.h',
],
'conditions': [
- ['cld_version==0 or cld_version==2', {
+ ['cld_version==2', {
'dependencies': [
'<(DEPTH)/third_party/cld_2/cld_2.gyp:cld_2',
],
+ 'sources': [
+ 'translate/content/renderer/data_file_renderer_cld_data_provider.cc',
+ 'translate/content/renderer/data_file_renderer_cld_data_provider.h',
+ ],
}],
],
},
diff --git a/chromium/components/ui_zoom.gypi b/chromium/components/ui_zoom.gypi
index 15e988dfc0e..ddab2cabb62 100644
--- a/chromium/components/ui_zoom.gypi
+++ b/chromium/components/ui_zoom.gypi
@@ -5,6 +5,7 @@
{
'targets': [
{
+ # GN version: //components/ui/zoom
'target_name': 'ui_zoom',
'type': 'static_library',
'include_dirs': [
diff --git a/chromium/components/upload_list.gypi b/chromium/components/upload_list.gypi
new file mode 100644
index 00000000000..e0bf6b14e3d
--- /dev/null
+++ b/chromium/components/upload_list.gypi
@@ -0,0 +1,25 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/upload_list
+ 'target_name': 'upload_list',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ '../base/base.gyp:base',
+ ],
+ 'sources': [
+ 'upload_list/crash_upload_list.cc',
+ 'upload_list/crash_upload_list.h',
+ 'upload_list/upload_list.cc',
+ 'upload_list/upload_list.h',
+ ],
+ },
+ ],
+}
diff --git a/chromium/components/url_formatter/BUILD.gn b/chromium/components/url_formatter/BUILD.gn
new file mode 100644
index 00000000000..3b777de5fa0
--- /dev/null
+++ b/chromium/components/url_formatter/BUILD.gn
@@ -0,0 +1,50 @@
+# 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.
+
+source_set("url_formatter") {
+ sources = [
+ "elide_url.cc",
+ "elide_url.h",
+ "url_fixer.cc",
+ "url_fixer.h",
+ "url_formatter.cc",
+ "url_formatter.h",
+ ]
+
+ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+ configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+
+ deps = [
+ "//base",
+ "//third_party/icu",
+ "//net",
+ "//url",
+ ]
+
+ if (!is_android) {
+ deps += [ "//ui/gfx" ]
+ }
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "elide_url_unittest.cc",
+ "url_fixer_unittest.cc",
+ "url_formatter_unittest.cc",
+ ]
+
+ deps = [
+ ":url_formatter",
+ "//base",
+ "//net",
+ "//testing/gtest",
+ "//ui/gfx",
+ "//url",
+ ]
+
+ if (is_android) {
+ deps -= [ "//ui/gfx" ]
+ }
+}
diff --git a/chromium/components/url_formatter/DEPS b/chromium/components/url_formatter/DEPS
new file mode 100644
index 00000000000..3c1754fe387
--- /dev/null
+++ b/chromium/components/url_formatter/DEPS
@@ -0,0 +1,11 @@
+include_rules = [
+ # This is a shared component (Mandoline, iOS, content), and as such, MUST NOT
+ # depend on content or other components that do.
+ "-components/html_viewer",
+ "-content",
+ "-ios",
+ "-mandoline",
+
+ "+net",
+ "+ui/gfx",
+]
diff --git a/chromium/components/url_formatter/OWNERS b/chromium/components/url_formatter/OWNERS
new file mode 100644
index 00000000000..49e5b762bab
--- /dev/null
+++ b/chromium/components/url_formatter/OWNERS
@@ -0,0 +1,9 @@
+pkasting@chromium.org
+
+# Backup reviewer
+brettw@chromium.org
+
+# Changes to FormatUrlForSecurityDisplay require a security review to avoid
+# introducing security bugs.
+per-file elide_url.*=palmer@chromium.org
+per-file elide_url.*=felt@chromium.org
diff --git a/chromium/components/url_formatter/elide_url.cc b/chromium/components/url_formatter/elide_url.cc
new file mode 100644
index 00000000000..80e7866880d
--- /dev/null
+++ b/chromium/components/url_formatter/elide_url.cc
@@ -0,0 +1,370 @@
+// 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/url_formatter/elide_url.h"
+
+#include "base/logging.h"
+#include "base/strings/string_split.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/url_formatter/url_formatter.h"
+#include "net/base/escape.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "url/gurl.h"
+#include "url/url_constants.h"
+
+#if !defined(OS_ANDROID)
+#include "ui/gfx/text_elider.h" // nogncheck
+#include "ui/gfx/text_utils.h" // nogncheck
+#endif
+
+namespace {
+
+#if !defined(OS_ANDROID)
+const base::char16 kDot = '.';
+
+// Build a path from the first |num_components| elements in |path_elements|.
+// Prepends |path_prefix|, appends |filename|, inserts ellipsis if appropriate.
+base::string16 BuildPathFromComponents(
+ const base::string16& path_prefix,
+ const std::vector<base::string16>& path_elements,
+ const base::string16& filename,
+ size_t num_components) {
+ // Add the initial elements of the path.
+ base::string16 path = path_prefix;
+
+ // Build path from first |num_components| elements.
+ for (size_t j = 0; j < num_components; ++j)
+ path += path_elements[j] + gfx::kForwardSlash;
+
+ // Add |filename|, ellipsis if necessary.
+ if (num_components != (path_elements.size() - 1))
+ path += base::string16(gfx::kEllipsisUTF16) + gfx::kForwardSlash;
+ path += filename;
+
+ return path;
+}
+
+// Takes a prefix (Domain, or Domain+subdomain) and a collection of path
+// components and elides if possible. Returns a string containing the longest
+// possible elided path, or an empty string if elision is not possible.
+base::string16 ElideComponentizedPath(
+ const base::string16& url_path_prefix,
+ const std::vector<base::string16>& url_path_elements,
+ const base::string16& url_filename,
+ const base::string16& url_query,
+ const gfx::FontList& font_list,
+ float available_pixel_width) {
+ const size_t url_path_number_of_elements = url_path_elements.size();
+
+ CHECK(url_path_number_of_elements);
+ for (size_t i = url_path_number_of_elements - 1; i > 0; --i) {
+ base::string16 elided_path = BuildPathFromComponents(
+ url_path_prefix, url_path_elements, url_filename, i);
+ if (available_pixel_width >= gfx::GetStringWidthF(elided_path, font_list))
+ return gfx::ElideText(elided_path + url_query, font_list,
+ available_pixel_width, gfx::ELIDE_TAIL);
+ }
+
+ return base::string16();
+}
+
+// Splits the hostname in the |url| into sub-strings for the full hostname,
+// the domain (TLD+1), and the subdomain (everything leading the domain).
+void SplitHost(const GURL& url,
+ base::string16* url_host,
+ base::string16* url_domain,
+ base::string16* url_subdomain) {
+ // Get Host.
+ *url_host = base::UTF8ToUTF16(url.host());
+
+ // Get domain and registry information from the URL.
+ *url_domain =
+ base::UTF8ToUTF16(net::registry_controlled_domains::GetDomainAndRegistry(
+ url, net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES));
+ if (url_domain->empty())
+ *url_domain = *url_host;
+
+ // Add port if required.
+ if (!url.port().empty()) {
+ *url_host += base::UTF8ToUTF16(":" + url.port());
+ *url_domain += base::UTF8ToUTF16(":" + url.port());
+ }
+
+ // Get sub domain.
+ const size_t domain_start_index = url_host->find(*url_domain);
+ base::string16 kWwwPrefix = base::UTF8ToUTF16("www.");
+ if (domain_start_index != base::string16::npos)
+ *url_subdomain = url_host->substr(0, domain_start_index);
+ if ((*url_subdomain == kWwwPrefix || url_subdomain->empty() ||
+ url.SchemeIsFile())) {
+ url_subdomain->clear();
+ }
+}
+
+#endif // !defined(OS_ANDROID)
+
+base::string16 FormatUrlForSecurityDisplayInternal(const GURL& url,
+ const std::string& languages,
+ bool omit_scheme) {
+ if (!url.is_valid() || url.is_empty() || !url.IsStandard())
+ return url_formatter::FormatUrl(url, languages);
+
+ const base::string16 colon(base::ASCIIToUTF16(":"));
+ const base::string16 scheme_separator(
+ base::ASCIIToUTF16(url::kStandardSchemeSeparator));
+
+ if (url.SchemeIsFile()) {
+ return base::ASCIIToUTF16(url::kFileScheme) + scheme_separator +
+ base::UTF8ToUTF16(url.path());
+ }
+
+ if (url.SchemeIsFileSystem()) {
+ const GURL* inner_url = url.inner_url();
+ if (inner_url->SchemeIsFile()) {
+ return base::ASCIIToUTF16(url::kFileSystemScheme) + colon +
+ FormatUrlForSecurityDisplayInternal(*inner_url, languages,
+ false /*omit_scheme*/) +
+ base::UTF8ToUTF16(url.path());
+ }
+ return base::ASCIIToUTF16(url::kFileSystemScheme) + colon +
+ FormatUrlForSecurityDisplayInternal(*inner_url, languages,
+ false /*omit_scheme*/);
+ }
+
+ const GURL origin = url.GetOrigin();
+ const std::string& scheme = origin.scheme();
+ const std::string& host = origin.host();
+
+ base::string16 result;
+ if (!omit_scheme || !url.SchemeIsHTTPOrHTTPS())
+ result = base::UTF8ToUTF16(scheme) + scheme_separator;
+ result += base::UTF8ToUTF16(host);
+
+ const int port = origin.IntPort();
+ const int default_port = url::DefaultPortForScheme(
+ scheme.c_str(), static_cast<int>(scheme.length()));
+ if (port != url::PORT_UNSPECIFIED && port != default_port)
+ result += colon + base::UTF8ToUTF16(origin.port());
+
+ return result;
+}
+
+} // namespace
+
+namespace url_formatter {
+
+#if !defined(OS_ANDROID)
+
+// TODO(pkasting): http://crbug.com/77883 This whole function gets
+// kerning/ligatures/etc. issues potentially wrong by assuming that the width of
+// a rendered string is always the sum of the widths of its substrings. Also I
+// suspect it could be made simpler.
+base::string16 ElideUrl(const GURL& url,
+ const gfx::FontList& font_list,
+ float available_pixel_width,
+ const std::string& languages) {
+ // Get a formatted string and corresponding parsing of the url.
+ url::Parsed parsed;
+ const base::string16 url_string = url_formatter::FormatUrl(
+ url, languages, url_formatter::kFormatUrlOmitAll,
+ net::UnescapeRule::SPACES, &parsed, nullptr, nullptr);
+ if (available_pixel_width <= 0)
+ return url_string;
+
+ // If non-standard, return plain eliding.
+ if (!url.IsStandard())
+ return gfx::ElideText(url_string, font_list, available_pixel_width,
+ gfx::ELIDE_TAIL);
+
+ // Now start eliding url_string to fit within available pixel width.
+ // Fist pass - check to see whether entire url_string fits.
+ const float pixel_width_url_string =
+ gfx::GetStringWidthF(url_string, font_list);
+ if (available_pixel_width >= pixel_width_url_string)
+ return url_string;
+
+ // Get the path substring, including query and reference.
+ const size_t path_start_index = parsed.path.begin;
+ const size_t path_len = parsed.path.len;
+ base::string16 url_path_query_etc = url_string.substr(path_start_index);
+ base::string16 url_path = url_string.substr(path_start_index, path_len);
+
+ // Return general elided text if url minus the query fits.
+ const base::string16 url_minus_query =
+ url_string.substr(0, path_start_index + path_len);
+ if (available_pixel_width >= gfx::GetStringWidthF(url_minus_query, font_list))
+ return gfx::ElideText(url_string, font_list, available_pixel_width,
+ gfx::ELIDE_TAIL);
+
+ base::string16 url_host;
+ base::string16 url_domain;
+ base::string16 url_subdomain;
+ SplitHost(url, &url_host, &url_domain, &url_subdomain);
+
+ // If this is a file type, the path is now defined as everything after ":".
+ // For example, "C:/aa/aa/bb", the path is "/aa/bb/cc". Interesting, the
+ // domain is now C: - this is a nice hack for eliding to work pleasantly.
+ if (url.SchemeIsFile()) {
+ // Split the path string using ":"
+ const base::string16 kColon(1, ':');
+ std::vector<base::string16> file_path_split = base::SplitString(
+ url_path, kColon, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ if (file_path_split.size() > 1) { // File is of type "file:///C:/.."
+ url_host.clear();
+ url_domain.clear();
+ url_subdomain.clear();
+
+ url_host = url_domain = file_path_split.at(0).substr(1) + kColon;
+ url_path_query_etc = url_path = file_path_split.at(1);
+ }
+ }
+
+ // Second Pass - remove scheme - the rest fits.
+ const float pixel_width_url_host = gfx::GetStringWidthF(url_host, font_list);
+ const float pixel_width_url_path =
+ gfx::GetStringWidthF(url_path_query_etc, font_list);
+ if (available_pixel_width >= pixel_width_url_host + pixel_width_url_path)
+ return url_host + url_path_query_etc;
+
+ // Third Pass: Subdomain, domain and entire path fits.
+ const float pixel_width_url_domain =
+ gfx::GetStringWidthF(url_domain, font_list);
+ const float pixel_width_url_subdomain =
+ gfx::GetStringWidthF(url_subdomain, font_list);
+ if (available_pixel_width >=
+ pixel_width_url_subdomain + pixel_width_url_domain + pixel_width_url_path)
+ return url_subdomain + url_domain + url_path_query_etc;
+
+ // Query element.
+ base::string16 url_query;
+ const float kPixelWidthDotsTrailer =
+ gfx::GetStringWidthF(base::string16(gfx::kEllipsisUTF16), font_list);
+ if (parsed.query.is_nonempty()) {
+ url_query = base::UTF8ToUTF16("?") + url_string.substr(parsed.query.begin);
+ if (available_pixel_width >=
+ (pixel_width_url_subdomain + pixel_width_url_domain +
+ pixel_width_url_path - gfx::GetStringWidthF(url_query, font_list))) {
+ return gfx::ElideText(url_subdomain + url_domain + url_path_query_etc,
+ font_list, available_pixel_width, gfx::ELIDE_TAIL);
+ }
+ }
+
+ // Parse url_path using '/'.
+ std::vector<base::string16> url_path_elements =
+ base::SplitString(url_path, base::string16(1, gfx::kForwardSlash),
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+
+ // Get filename - note that for a path ending with /
+ // such as www.google.com/intl/ads/, the file name is ads/.
+ base::string16 url_filename(
+ url_path_elements.empty() ? base::string16() : url_path_elements.back());
+ size_t url_path_number_of_elements = url_path_elements.size();
+ if (url_filename.empty() && (url_path_number_of_elements > 1)) {
+ // Path ends with a '/'.
+ --url_path_number_of_elements;
+ url_filename =
+ url_path_elements[url_path_number_of_elements - 1] + gfx::kForwardSlash;
+ }
+
+ const size_t kMaxNumberOfUrlPathElementsAllowed = 1024;
+ if (url_path_number_of_elements <= 1 ||
+ url_path_number_of_elements > kMaxNumberOfUrlPathElementsAllowed) {
+ // No path to elide, or too long of a path (could overflow in loop below)
+ // Just elide this as a text string.
+ return gfx::ElideText(url_subdomain + url_domain + url_path_query_etc,
+ font_list, available_pixel_width, gfx::ELIDE_TAIL);
+ }
+
+ // Start eliding the path and replacing elements by ".../".
+ const base::string16 kEllipsisAndSlash =
+ base::string16(gfx::kEllipsisUTF16) + gfx::kForwardSlash;
+ const float pixel_width_ellipsis_slash =
+ gfx::GetStringWidthF(kEllipsisAndSlash, font_list);
+
+ // Check with both subdomain and domain.
+ base::string16 elided_path = ElideComponentizedPath(
+ url_subdomain + url_domain, url_path_elements, url_filename, url_query,
+ font_list, available_pixel_width);
+ if (!elided_path.empty())
+ return elided_path;
+
+ // Check with only domain.
+ // If a subdomain is present, add an ellipsis before domain.
+ // This is added only if the subdomain pixel width is larger than
+ // the pixel width of kEllipsis. Otherwise, subdomain remains,
+ // which means that this case has been resolved earlier.
+ base::string16 url_elided_domain = url_subdomain + url_domain;
+ if (pixel_width_url_subdomain > kPixelWidthDotsTrailer) {
+ if (!url_subdomain.empty())
+ url_elided_domain = kEllipsisAndSlash[0] + url_domain;
+ else
+ url_elided_domain = url_domain;
+
+ elided_path = ElideComponentizedPath(url_elided_domain, url_path_elements,
+ url_filename, url_query, font_list,
+ available_pixel_width);
+
+ if (!elided_path.empty())
+ return elided_path;
+ }
+
+ // Return elided domain/.../filename anyway.
+ base::string16 final_elided_url_string(url_elided_domain);
+ const float url_elided_domain_width =
+ gfx::GetStringWidthF(url_elided_domain, font_list);
+
+ // A hack to prevent trailing ".../...".
+ if ((available_pixel_width - url_elided_domain_width) >
+ pixel_width_ellipsis_slash + kPixelWidthDotsTrailer +
+ gfx::GetStringWidthF(base::ASCIIToUTF16("UV"), font_list)) {
+ final_elided_url_string += BuildPathFromComponents(
+ base::string16(), url_path_elements, url_filename, 1);
+ } else {
+ final_elided_url_string += url_path;
+ }
+
+ return gfx::ElideText(final_elided_url_string, font_list,
+ available_pixel_width, gfx::ELIDE_TAIL);
+}
+
+base::string16 ElideHost(const GURL& url,
+ const gfx::FontList& font_list,
+ float available_pixel_width) {
+ base::string16 url_host;
+ base::string16 url_domain;
+ base::string16 url_subdomain;
+ SplitHost(url, &url_host, &url_domain, &url_subdomain);
+
+ const float pixel_width_url_host = gfx::GetStringWidthF(url_host, font_list);
+ if (available_pixel_width >= pixel_width_url_host)
+ return url_host;
+
+ if (url_subdomain.empty())
+ return url_domain;
+
+ const float pixel_width_url_domain =
+ gfx::GetStringWidthF(url_domain, font_list);
+ float subdomain_width = available_pixel_width - pixel_width_url_domain;
+ if (subdomain_width <= 0)
+ return base::string16(gfx::kEllipsisUTF16) + kDot + url_domain;
+
+ const base::string16 elided_subdomain = gfx::ElideText(
+ url_subdomain, font_list, subdomain_width, gfx::ELIDE_HEAD);
+ return elided_subdomain + url_domain;
+}
+
+#endif // !defined(OS_ANDROID)
+
+base::string16 FormatUrlForSecurityDisplay(const GURL& url,
+ const std::string& languages) {
+ return FormatUrlForSecurityDisplayInternal(url, languages, false);
+}
+
+base::string16 FormatUrlForSecurityDisplayOmitScheme(
+ const GURL& url,
+ const std::string& languages) {
+ return FormatUrlForSecurityDisplayInternal(url, languages, true);
+}
+
+} // namespace url_formatter
diff --git a/chromium/components/url_formatter/elide_url.h b/chromium/components/url_formatter/elide_url.h
new file mode 100644
index 00000000000..74777deac34
--- /dev/null
+++ b/chromium/components/url_formatter/elide_url.h
@@ -0,0 +1,86 @@
+// 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.
+//
+// This file defines utility functions for eliding URLs.
+
+#ifndef COMPONENTS_URL_FORMATTER_ELIDE_URL_H_
+#define COMPONENTS_URL_FORMATTER_ELIDE_URL_H_
+
+#include <string>
+
+#include "base/strings/string16.h"
+
+class GURL;
+
+namespace gfx {
+class FontList;
+}
+
+namespace url_formatter {
+
+// ElideUrl and Elide host require
+// gfx::GetStringWidthF which is not implemented in Android
+#if !defined(OS_ANDROID)
+// This function takes a GURL object and elides it. It returns a string
+// which composed of parts from subdomain, domain, path, filename and query.
+// A "..." is added automatically at the end if the elided string is bigger
+// than the |available_pixel_width|. For |available_pixel_width| == 0, a
+// formatted, but un-elided, string is returned. |languages| is a comma
+// separated list of ISO 639 language codes and is used to determine what
+// characters are understood by a user. It should come from
+// |prefs::kAcceptLanguages|.
+//
+// Note: in RTL locales, if the URL returned by this function is going to be
+// displayed in the UI, then it is likely that the string needs to be marked
+// as an LTR string (using base::i18n::WrapStringWithLTRFormatting()) so that it
+// is displayed properly in an RTL context. Please refer to
+// http://crbug.com/6487 for more information.
+base::string16 ElideUrl(const GURL& url,
+ const gfx::FontList& font_list,
+ float available_pixel_width,
+ const std::string& languages);
+
+// This function takes a GURL object and elides the host to fit within
+// the given width. The function will never elide past the TLD+1 point,
+// but after that, will leading-elide the domain name to fit the width.
+// Example: http://sub.domain.com ---> "...domain.com", or "...b.domain.com"
+// depending on the width.
+base::string16 ElideHost(const GURL& host_url,
+ const gfx::FontList& font_list,
+ float available_pixel_width);
+#endif // !defined(OS_ANDROID)
+
+// This is a convenience function for formatting a URL in a concise and
+// human-friendly way, to help users make security-related decisions (or in
+// other circumstances when people need to distinguish sites, origins, or
+// otherwise-simplified URLs from each other).
+//
+// Internationalized domain names (IDN) may be presented in Unicode if
+// |languages| accepts the Unicode representation (see
+// |url_formatter::FormatUrl| for more details on the algorithm).
+//
+// - Omits the path for standard schemes, excepting file and filesystem.
+// - Omits the port if it is the default for the scheme.
+//
+// Do not use this for URLs which will be parsed or sent to other applications.
+//
+// Generally, set prefer this function to
+// |FormatUrlForSecurityDisplayOmitScheme| unless there is plenty of indication
+// as to whether the origin is secure elsewhere in the UX. For example, in
+// Chrome's Origin Info Bubble, there are icons and strings indicating origin
+// (non-)security. But in the HTTP Basic Auth prompt (for example), the scheme
+// may be the only indicator.
+base::string16 FormatUrlForSecurityDisplay(const GURL& origin,
+ const std::string& languages);
+
+// Just like |FormatUrlForSecurityDisplay|, but also:
+//
+// - Omits the scheme if SchemeIsHTTPOrHTTPS().
+base::string16 FormatUrlForSecurityDisplayOmitScheme(
+ const GURL& origin,
+ const std::string& languages);
+
+} // namespace url_formatter
+
+#endif // COMPONENTS_URL_FORMATTER_ELIDE_URL_H_
diff --git a/chromium/components/url_formatter/elide_url_unittest.cc b/chromium/components/url_formatter/elide_url_unittest.cc
new file mode 100644
index 00000000000..f0f4fbb3439
--- /dev/null
+++ b/chromium/components/url_formatter/elide_url_unittest.cc
@@ -0,0 +1,366 @@
+// 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/url_formatter/elide_url.h"
+
+#include "base/ios/ios_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+#if !defined(OS_ANDROID)
+#include "ui/gfx/font_list.h" // nogncheck
+#include "ui/gfx/text_elider.h" // nogncheck
+#include "ui/gfx/text_utils.h" // nogncheck
+#endif
+
+namespace {
+
+struct Testcase {
+ const std::string input;
+ const std::string output;
+ enum SupportedPlatforms {
+ ALL = 0,
+ NO_IOS9_OR_LATER,
+ NO_IOS,
+ } platforms;
+};
+
+#if !defined(OS_ANDROID)
+void RunUrlTest(Testcase* testcases, size_t num_testcases) {
+ static const gfx::FontList font_list;
+ for (size_t i = 0; i < num_testcases; ++i) {
+ const GURL url(testcases[i].input);
+ // Should we test with non-empty language list?
+ // That's kinda redundant with net_util_unittests.
+ const float available_width =
+ gfx::GetStringWidthF(base::UTF8ToUTF16(testcases[i].output), font_list);
+ EXPECT_EQ(base::UTF8ToUTF16(testcases[i].output),
+ url_formatter::ElideUrl(url, font_list, available_width,
+ std::string()));
+ }
+}
+
+// Test eliding of commonplace URLs.
+TEST(TextEliderTest, TestGeneralEliding) {
+ const std::string kEllipsisStr(gfx::kEllipsis);
+ Testcase testcases[] = {
+ {"http://www.google.com/intl/en/ads/", "www.google.com/intl/en/ads/"},
+ {"http://www.google.com/intl/en/ads/", "www.google.com/intl/en/ads/"},
+ {"http://www.google.com/intl/en/ads/",
+ "google.com/intl/" + kEllipsisStr + "/ads/"},
+ {"http://www.google.com/intl/en/ads/",
+ "google.com/" + kEllipsisStr + "/ads/"},
+ {"http://www.google.com/intl/en/ads/", "google.com/" + kEllipsisStr},
+ {"http://www.google.com/intl/en/ads/", "goog" + kEllipsisStr},
+ {"https://subdomain.foo.com/bar/filename.html",
+ "subdomain.foo.com/bar/filename.html"},
+ {"https://subdomain.foo.com/bar/filename.html",
+ "subdomain.foo.com/" + kEllipsisStr + "/filename.html"},
+ {"http://subdomain.foo.com/bar/filename.html",
+ kEllipsisStr + "foo.com/" + kEllipsisStr + "/filename.html"},
+ {"http://www.google.com/intl/en/ads/?aLongQueryWhichIsNotRequired",
+ "www.google.com/intl/en/ads/?aLongQ" + kEllipsisStr},
+ };
+
+ RunUrlTest(testcases, arraysize(testcases));
+}
+
+// When there is very little space available, the elision code will shorten
+// both path AND file name to an ellipsis - ".../...". To avoid this result,
+// there is a hack in place that simply treats them as one string in this
+// case.
+TEST(TextEliderTest, TestTrailingEllipsisSlashEllipsisHack) {
+ const std::string kEllipsisStr(gfx::kEllipsis);
+
+ // Very little space, would cause double ellipsis.
+ gfx::FontList font_list;
+ GURL url("http://battersbox.com/directory/foo/peter_paul_and_mary.html");
+ float available_width = gfx::GetStringWidthF(
+ base::UTF8ToUTF16("battersbox.com/" + kEllipsisStr + "/" + kEllipsisStr),
+ font_list);
+
+ // Create the expected string, after elision. Depending on font size, the
+ // directory might become /dir... or /di... or/d... - it never should be
+ // shorter than that. (If it is, the font considers d... to be longer
+ // than .../... - that should never happen).
+ ASSERT_GT(
+ gfx::GetStringWidthF(base::UTF8ToUTF16(kEllipsisStr + "/" + kEllipsisStr),
+ font_list),
+ gfx::GetStringWidthF(base::UTF8ToUTF16("d" + kEllipsisStr), font_list));
+ GURL long_url("http://battersbox.com/directorynameisreallylongtoforcetrunc");
+ base::string16 expected = url_formatter::ElideUrl(
+ long_url, font_list, available_width, std::string());
+ // Ensure that the expected result still contains part of the directory name.
+ ASSERT_GT(expected.length(), std::string("battersbox.com/d").length());
+ EXPECT_EQ(expected, url_formatter::ElideUrl(url, font_list, available_width,
+ std::string()));
+
+ // More space available - elide directories, partially elide filename.
+ Testcase testcases[] = {
+ {"http://battersbox.com/directory/foo/peter_paul_and_mary.html",
+ "battersbox.com/" + kEllipsisStr + "/peter" + kEllipsisStr},
+ };
+ RunUrlTest(testcases, arraysize(testcases));
+}
+
+// Test eliding of empty strings, URLs with ports, passwords, queries, etc.
+TEST(TextEliderTest, TestMoreEliding) {
+ const std::string kEllipsisStr(gfx::kEllipsis);
+ Testcase testcases[] = {
+ {"http://www.google.com/foo?bar", "www.google.com/foo?bar"},
+ {"http://xyz.google.com/foo?bar", "xyz.google.com/foo?" + kEllipsisStr},
+ {"http://xyz.google.com/foo?bar", "xyz.google.com/foo" + kEllipsisStr},
+ {"http://xyz.google.com/foo?bar", "xyz.google.com/fo" + kEllipsisStr},
+ {"http://a.b.com/pathname/c?d", "a.b.com/" + kEllipsisStr + "/c?d"},
+ {"", ""},
+ {"http://foo.bar..example.com...hello/test/filename.html",
+ "foo.bar..example.com...hello/" + kEllipsisStr + "/filename.html"},
+ {"http://foo.bar../", "foo.bar.."},
+ {"http://xn--1lq90i.cn/foo", "\xe5\x8c\x97\xe4\xba\xac.cn/foo"},
+ {"http://me:mypass@secrethost.com:99/foo?bar#baz",
+ "secrethost.com:99/foo?bar#baz"},
+ {"http://me:mypass@ss%xxfdsf.com/foo", "ss%25xxfdsf.com/foo"},
+ {"mailto:elgoato@elgoato.com", "mailto:elgoato@elgoato.com"},
+ {"javascript:click(0)", "javascript:click(0)"},
+ {"https://chess.eecs.berkeley.edu:4430/login/arbitfilename",
+ "chess.eecs.berkeley.edu:4430/login/arbitfilename"},
+ {"https://chess.eecs.berkeley.edu:4430/login/arbitfilename",
+ kEllipsisStr + "berkeley.edu:4430/" + kEllipsisStr + "/arbitfilename"},
+
+ // Unescaping.
+ {"http://www/%E4%BD%A0%E5%A5%BD?q=%E4%BD%A0%E5%A5%BD#\xe4\xbd\xa0",
+ "www/\xe4\xbd\xa0\xe5\xa5\xbd?q=\xe4\xbd\xa0\xe5\xa5\xbd#\xe4\xbd\xa0"},
+
+ // Invalid unescaping for path. The ref will always be valid UTF-8. We
+ // don't
+ // bother to do too many edge cases, since these are handled by the
+ // escaper
+ // unittest.
+ {"http://www/%E4%A0%E5%A5%BD?q=%E4%BD%A0%E5%A5%BD#\xe4\xbd\xa0",
+ "www/%E4%A0%E5%A5%BD?q=\xe4\xbd\xa0\xe5\xa5\xbd#\xe4\xbd\xa0"},
+ };
+
+ RunUrlTest(testcases, arraysize(testcases));
+}
+
+// Test eliding of file: URLs.
+TEST(TextEliderTest, TestFileURLEliding) {
+ const std::string kEllipsisStr(gfx::kEllipsis);
+ Testcase testcases[] = {
+ {"file:///C:/path1/path2/path3/filename",
+ "file:///C:/path1/path2/path3/filename"},
+ {"file:///C:/path1/path2/path3/filename", "C:/path1/path2/path3/filename"},
+// GURL parses "file:///C:path" differently on windows than it does on posix.
+#if defined(OS_WIN)
+ {"file:///C:path1/path2/path3/filename",
+ "C:/path1/path2/" + kEllipsisStr + "/filename"},
+ {"file:///C:path1/path2/path3/filename",
+ "C:/path1/" + kEllipsisStr + "/filename"},
+ {"file:///C:path1/path2/path3/filename",
+ "C:/" + kEllipsisStr + "/filename"},
+#endif // defined(OS_WIN)
+ {"file://filer/foo/bar/file", "filer/foo/bar/file"},
+ {"file://filer/foo/bar/file", "filer/foo/" + kEllipsisStr + "/file"},
+ {"file://filer/foo/bar/file", "filer/" + kEllipsisStr + "/file"},
+ {"file://filer/foo/", "file://filer/foo/"},
+ {"file://filer/foo/", "filer/foo/"},
+ {"file://filer/foo/", "filer" + kEllipsisStr},
+ // Eliding file URLs with nothing after the ':' shouldn't crash.
+ {"file:///aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:", "aaa" + kEllipsisStr},
+ {"file:///aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:/", "aaa" + kEllipsisStr},
+ };
+
+ RunUrlTest(testcases, arraysize(testcases));
+}
+
+TEST(TextEliderTest, TestHostEliding) {
+ const std::string kEllipsisStr(gfx::kEllipsis);
+ Testcase testcases[] = {
+ {"http://google.com", "google.com"},
+ // iOS width calculations are off by a letter from other platforms for
+ // strings with too many kerned letters on the default font set.
+ // TODO(rohitrao): Fix secure_display::ElideHost for iOS
+ // (crbug.com/517604).
+ {"http://subdomain.google.com", kEllipsisStr + ".google.com",
+ Testcase::NO_IOS9_OR_LATER},
+ {"http://reallyreallyreallylongdomainname.com",
+ "reallyreallyreallylongdomainname.com"},
+ {"http://a.b.c.d.e.f.com", kEllipsisStr + "f.com",
+ Testcase::NO_IOS9_OR_LATER},
+ {"http://foo", "foo"},
+ {"http://foo.bar", "foo.bar"},
+ {"http://subdomain.foo.bar", kEllipsisStr + "in.foo.bar",
+ Testcase::NO_IOS9_OR_LATER},
+ {"http://subdomain.reallylongdomainname.com",
+ kEllipsisStr + "ain.reallylongdomainname.com", Testcase::NO_IOS},
+ {"http://a.b.c.d.e.f.com", kEllipsisStr + ".e.f.com", Testcase::NO_IOS},
+ };
+
+ for (size_t i = 0; i < arraysize(testcases); ++i) {
+#if defined(OS_IOS)
+ if (testcases[i].platforms == Testcase::NO_IOS ||
+ (testcases[i].platforms == Testcase::NO_IOS9_OR_LATER &&
+ base::ios::IsRunningOnIOS9OrLater())) {
+ continue;
+ }
+#endif
+ const float available_width = gfx::GetStringWidthF(
+ base::UTF8ToUTF16(testcases[i].output), gfx::FontList());
+ EXPECT_EQ(base::UTF8ToUTF16(testcases[i].output),
+ url_formatter::ElideHost(GURL(testcases[i].input),
+ gfx::FontList(), available_width));
+ }
+
+ // Trying to elide to a really short length will still keep the full TLD+1
+ EXPECT_EQ(
+ base::ASCIIToUTF16("google.com"),
+ url_formatter::ElideHost(GURL("http://google.com"), gfx::FontList(), 2));
+ EXPECT_EQ(base::UTF8ToUTF16(kEllipsisStr + ".google.com"),
+ url_formatter::ElideHost(GURL("http://subdomain.google.com"),
+ gfx::FontList(), 2));
+ EXPECT_EQ(
+ base::ASCIIToUTF16("foo.bar"),
+ url_formatter::ElideHost(GURL("http://foo.bar"), gfx::FontList(), 2));
+}
+
+#endif // !defined(OS_ANDROID)
+
+TEST(TextEliderTest, FormatUrlForSecurityDisplay) {
+ struct OriginTestData {
+ const char* const description;
+ const char* const input;
+ const wchar_t* const output;
+ const wchar_t* const output_omit_scheme;
+ };
+
+ const OriginTestData tests[] = {
+ {"Empty URL", "", L"", L""},
+ {"HTTP URL", "http://www.google.com/", L"http://www.google.com",
+ L"www.google.com"},
+ {"HTTPS URL", "https://www.google.com/", L"https://www.google.com",
+ L"www.google.com"},
+ {"Standard HTTP port", "http://www.google.com:80/",
+ L"http://www.google.com", L"www.google.com"},
+ {"Standard HTTPS port", "https://www.google.com:443/",
+ L"https://www.google.com", L"www.google.com"},
+ {"Standard HTTP port, IDN Chinese",
+ "http://\xe4\xb8\xad\xe5\x9b\xbd.icom.museum:80",
+ L"http://xn--fiqs8s.icom.museum", L"xn--fiqs8s.icom.museum"},
+ {"HTTP URL, IDN Hebrew (RTL)",
+ "http://"
+ "\xd7\x90\xd7\x99\xd7\xa7\xd7\x95\xd7\xb4\xd7\x9d."
+ "\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c.museum/",
+ L"http://xn--4dbklr2c8d.xn--4dbrk0ce.museum",
+ L"xn--4dbklr2c8d.xn--4dbrk0ce.museum"},
+ {"HTTP URL with query string, IDN Arabic (RTL)",
+ "http://\xd9\x85\xd8\xb5\xd8\xb1.icom.museum/foo.html?yes=no",
+ L"http://xn--wgbh1c.icom.museum", L"xn--wgbh1c.icom.museum"},
+ {"Non-standard HTTP port", "http://www.google.com:9000/",
+ L"http://www.google.com:9000", L"www.google.com:9000"},
+ {"Non-standard HTTPS port", "https://www.google.com:9000/",
+ L"https://www.google.com:9000", L"www.google.com:9000"},
+ {"File URI", "file:///usr/example/file.html",
+ L"file:///usr/example/file.html", L"file:///usr/example/file.html"},
+ {"File URI with hostname", "file://localhost/usr/example/file.html",
+ L"file:///usr/example/file.html", L"file:///usr/example/file.html"},
+ {"UNC File URI 1", "file:///CONTOSO/accounting/money.xls",
+ L"file:///CONTOSO/accounting/money.xls",
+ L"file:///CONTOSO/accounting/money.xls"},
+ {"UNC File URI 2",
+ "file:///C:/Program%20Files/Music/Web%20Sys/main.html?REQUEST=RADIO",
+ L"file:///C:/Program%20Files/Music/Web%20Sys/main.html",
+ L"file:///C:/Program%20Files/Music/Web%20Sys/main.html"},
+ {"HTTP URL with path", "http://www.google.com/test.html",
+ L"http://www.google.com", L"www.google.com"},
+ {"HTTPS URL with path", "https://www.google.com/test.html",
+ L"https://www.google.com", L"www.google.com"},
+ {"Unusual secure scheme (wss)", "wss://www.google.com/",
+ L"wss://www.google.com", L"wss://www.google.com"},
+ {"Unusual non-secure scheme (gopher)", "gopher://www.google.com/",
+ L"gopher://www.google.com", L"gopher://www.google.com"},
+ {"Unlisted scheme (chrome)", "chrome://version", L"chrome://version",
+ L"chrome://version"},
+ {"HTTP IP address", "http://173.194.65.103", L"http://173.194.65.103",
+ L"173.194.65.103"},
+ {"HTTPS IP address", "https://173.194.65.103", L"https://173.194.65.103",
+ L"173.194.65.103"},
+ {"HTTP IPv6 address", "http://[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]/",
+ L"http://[fe80::202:b3ff:fe1e:8329]", L"[fe80::202:b3ff:fe1e:8329]"},
+ {"HTTPS IPv6 address with port", "https://[2001:db8:0:1]:443/",
+ L"https://[2001:db8:0:1]", L"https://[2001:db8:0:1]"},
+ {"HTTPS IP address, non-default port", "https://173.194.65.103:8443",
+ L"https://173.194.65.103:8443", L"173.194.65.103:8443"},
+ {"HTTP filesystem: URL with path",
+ "filesystem:http://www.google.com/temporary/test.html",
+ L"filesystem:http://www.google.com",
+ L"filesystem:http://www.google.com"},
+ {"File filesystem: URL with path",
+ "filesystem:file://localhost/temporary/stuff/test.html?z=fun&goat=billy",
+ L"filesystem:file:///temporary/stuff/test.html",
+ L"filesystem:file:///temporary/stuff/test.html"},
+ {"Invalid scheme 1", "twelve://www.cyber.org/wow.php",
+ L"twelve://www.cyber.org/wow.php", L"twelve://www.cyber.org/wow.php"},
+ {"Invalid scheme 2", "://www.cyber.org/wow.php",
+ L"://www.cyber.org/wow.php", L"://www.cyber.org/wow.php"},
+ {"Invalid host 1", "https://www.cyber../wow.php", L"https://www.cyber..",
+ L"www.cyber.."},
+ {"Invalid host 2", "https://www...cyber/wow.php", L"https://www...cyber",
+ L"www...cyber"},
+ {"Invalid port 1", "https://173.194.65.103:000",
+ L"https://173.194.65.103:0", L"173.194.65.103:0"},
+ {"Invalid port 2", "https://173.194.65.103:gruffle",
+ L"https://173.194.65.103:gruffle", L"https://173.194.65.103:gruffle"},
+ {"Invalid port 3", "https://173.194.65.103:/hello.aspx",
+ L"https://173.194.65.103", L"173.194.65.103"},
+ {"Trailing dot in DNS name", "https://www.example.com./get/goat",
+ L"https://www.example.com.", L"www.example.com."},
+ {"Blob URL",
+ "blob:http%3A//www.html5rocks.com/4d4ff040-6d61-4446-86d3-13ca07ec9ab9",
+ L"blob:http%3A//www.html5rocks.com/"
+ L"4d4ff040-6d61-4446-86d3-13ca07ec9ab9",
+ L"blob:http%3A//www.html5rocks.com/"
+ L"4d4ff040-6d61-4446-86d3-13ca07ec9ab9"}};
+
+ const char languages[] = "zh-TW,en-US,en,am,ar-EG,ar";
+ for (size_t i = 0; i < arraysize(tests); ++i) {
+ base::string16 formatted = url_formatter::FormatUrlForSecurityDisplay(
+ GURL(tests[i].input), std::string());
+ EXPECT_EQ(base::WideToUTF16(tests[i].output), formatted)
+ << tests[i].description;
+
+ base::string16 formatted_omit_scheme =
+ url_formatter::FormatUrlForSecurityDisplayOmitScheme(
+ GURL(tests[i].input), std::string());
+ EXPECT_EQ(base::WideToUTF16(tests[i].output_omit_scheme),
+ formatted_omit_scheme)
+ << tests[i].description;
+
+ base::string16 formatted_with_languages =
+ url_formatter::FormatUrlForSecurityDisplay(GURL(tests[i].input),
+ languages);
+ EXPECT_EQ(base::WideToUTF16(tests[i].output), formatted_with_languages)
+ << tests[i].description;
+
+ base::string16 formatted_with_languages_omit_scheme =
+ url_formatter::FormatUrlForSecurityDisplayOmitScheme(
+ GURL(tests[i].input), languages);
+ EXPECT_EQ(base::WideToUTF16(tests[i].output_omit_scheme),
+ formatted_with_languages_omit_scheme)
+ << tests[i].description;
+ }
+
+ base::string16 formatted =
+ url_formatter::FormatUrlForSecurityDisplay(GURL(), std::string());
+ EXPECT_EQ(base::string16(), formatted)
+ << "Explicitly test the 0-argument GURL constructor";
+
+ base::string16 formatted_omit_scheme =
+ url_formatter::FormatUrlForSecurityDisplayOmitScheme(GURL(),
+ std::string());
+ EXPECT_EQ(base::string16(), formatted_omit_scheme)
+ << "Explicitly test the 0-argument GURL constructor";
+}
+
+} // namespace
diff --git a/chromium/components/url_formatter/url_fixer.cc b/chromium/components/url_formatter/url_fixer.cc
new file mode 100644
index 00000000000..c49a9022701
--- /dev/null
+++ b/chromium/components/url_formatter/url_fixer.cc
@@ -0,0 +1,673 @@
+// 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/url_formatter/url_fixer.h"
+
+#include <algorithm>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#if defined(OS_POSIX)
+#include "base/path_service.h"
+#endif
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/url_formatter/url_formatter.h"
+#include "net/base/escape.h"
+#include "net/base/filename_util.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "url/third_party/mozilla/url_parse.h"
+#include "url/url_file.h"
+#include "url/url_util.h"
+
+namespace url_formatter {
+
+const char* home_directory_override = nullptr;
+
+namespace {
+
+// Hardcode these constants to avoid dependences on //chrome and //content.
+const char kChromeUIScheme[] = "chrome";
+const char kChromeUIDefaultHost[] = "version";
+const char kViewSourceScheme[] = "view-source";
+
+// TODO(estade): Remove these ugly, ugly functions. They are only used in
+// SegmentURL. A url::Parsed object keeps track of a bunch of indices into
+// a url string, and these need to be updated when the URL is converted from
+// UTF8 to UTF16. Instead of this after-the-fact adjustment, we should parse it
+// in the correct string format to begin with.
+url::Component UTF8ComponentToUTF16Component(
+ const std::string& text_utf8,
+ const url::Component& component_utf8) {
+ if (component_utf8.len == -1)
+ return url::Component();
+
+ std::string before_component_string =
+ text_utf8.substr(0, component_utf8.begin);
+ std::string component_string =
+ text_utf8.substr(component_utf8.begin, component_utf8.len);
+ base::string16 before_component_string_16 =
+ base::UTF8ToUTF16(before_component_string);
+ base::string16 component_string_16 = base::UTF8ToUTF16(component_string);
+ url::Component component_16(before_component_string_16.length(),
+ component_string_16.length());
+ return component_16;
+}
+
+void UTF8PartsToUTF16Parts(const std::string& text_utf8,
+ const url::Parsed& parts_utf8,
+ url::Parsed* parts) {
+ if (base::IsStringASCII(text_utf8)) {
+ *parts = parts_utf8;
+ return;
+ }
+
+ parts->scheme = UTF8ComponentToUTF16Component(text_utf8, parts_utf8.scheme);
+ parts->username =
+ UTF8ComponentToUTF16Component(text_utf8, parts_utf8.username);
+ parts->password =
+ UTF8ComponentToUTF16Component(text_utf8, parts_utf8.password);
+ parts->host = UTF8ComponentToUTF16Component(text_utf8, parts_utf8.host);
+ parts->port = UTF8ComponentToUTF16Component(text_utf8, parts_utf8.port);
+ parts->path = UTF8ComponentToUTF16Component(text_utf8, parts_utf8.path);
+ parts->query = UTF8ComponentToUTF16Component(text_utf8, parts_utf8.query);
+ parts->ref = UTF8ComponentToUTF16Component(text_utf8, parts_utf8.ref);
+}
+
+base::TrimPositions TrimWhitespaceUTF8(const std::string& input,
+ base::TrimPositions positions,
+ std::string* output) {
+ // This implementation is not so fast since it converts the text encoding
+ // twice. Please feel free to file a bug if this function hurts the
+ // performance of Chrome.
+ DCHECK(base::IsStringUTF8(input));
+ base::string16 input16 = base::UTF8ToUTF16(input);
+ base::string16 output16;
+ base::TrimPositions result =
+ base::TrimWhitespace(input16, positions, &output16);
+ *output = base::UTF16ToUTF8(output16);
+ return result;
+}
+
+// does some basic fixes for input that we want to test for file-ness
+void PrepareStringForFileOps(const base::FilePath& text,
+ base::FilePath::StringType* output) {
+#if defined(OS_WIN)
+ base::TrimWhitespace(text.value(), base::TRIM_ALL, output);
+ replace(output->begin(), output->end(), '/', '\\');
+#else
+ TrimWhitespaceUTF8(text.value(), base::TRIM_ALL, output);
+#endif
+}
+
+// Tries to create a full path from |text|. If the result is valid and the
+// file exists, returns true and sets |full_path| to the result. Otherwise,
+// returns false and leaves |full_path| unchanged.
+bool ValidPathForFile(const base::FilePath::StringType& text,
+ base::FilePath* full_path) {
+ base::FilePath file_path = base::MakeAbsoluteFilePath(base::FilePath(text));
+ if (file_path.empty())
+ return false;
+
+ if (!base::PathExists(file_path))
+ return false;
+
+ *full_path = file_path;
+ return true;
+}
+
+#if defined(OS_POSIX)
+// Given a path that starts with ~, return a path that starts with an
+// expanded-out /user/foobar directory.
+std::string FixupHomedir(const std::string& text) {
+ DCHECK(text.length() > 0 && text[0] == '~');
+
+ if (text.length() == 1 || text[1] == '/') {
+ base::FilePath file_path;
+ if (home_directory_override)
+ file_path = base::FilePath(home_directory_override);
+ else
+ PathService::Get(base::DIR_HOME, &file_path);
+
+ // We'll probably break elsewhere if $HOME is undefined, but check here
+ // just in case.
+ if (file_path.value().empty())
+ return text;
+ // Append requires to be a relative path, so we have to cut all preceeding
+ // '/' characters.
+ size_t i = 1;
+ while (i < text.length() && text[i] == '/')
+ ++i;
+ return file_path.Append(text.substr(i)).value();
+ }
+
+// Otherwise, this is a path like ~foobar/baz, where we must expand to
+// user foobar's home directory. Officially, we should use getpwent(),
+// but that is a nasty blocking call.
+
+#if defined(OS_MACOSX)
+ static const char kHome[] = "/Users/";
+#else
+ static const char kHome[] = "/home/";
+#endif
+ return kHome + text.substr(1);
+}
+#endif
+
+// Tries to create a file: URL from |text| if it looks like a filename, even if
+// it doesn't resolve as a valid path or to an existing file. Returns a
+// (possibly invalid) file: URL in |fixed_up_url| for input beginning
+// with a drive specifier or "\\". Returns the unchanged input in other cases
+// (including file: URLs: these don't look like filenames).
+std::string FixupPath(const std::string& text) {
+ DCHECK(!text.empty());
+
+ base::FilePath::StringType filename;
+#if defined(OS_WIN)
+ base::FilePath input_path(base::UTF8ToWide(text));
+ PrepareStringForFileOps(input_path, &filename);
+
+ // Fixup Windows-style drive letters, where "C:" gets rewritten to "C|".
+ if (filename.length() > 1 && filename[1] == '|')
+ filename[1] = ':';
+#elif defined(OS_POSIX)
+ base::FilePath input_path(text);
+ PrepareStringForFileOps(input_path, &filename);
+ if (filename.length() > 0 && filename[0] == '~')
+ filename = FixupHomedir(filename);
+#endif
+
+ // Here, we know the input looks like a file.
+ GURL file_url = net::FilePathToFileURL(base::FilePath(filename));
+ if (file_url.is_valid()) {
+ return base::UTF16ToUTF8(url_formatter::FormatUrl(
+ file_url, std::string(), url_formatter::kFormatUrlOmitUsernamePassword,
+ net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr));
+ }
+
+ // Invalid file URL, just return the input.
+ return text;
+}
+
+// Checks |domain| to see if a valid TLD is already present. If not, appends
+// |desired_tld| to the domain, and prepends "www." unless it's already present.
+void AddDesiredTLD(const std::string& desired_tld, std::string* domain) {
+ if (desired_tld.empty() || domain->empty())
+ return;
+
+ // Check the TLD. If the return value is positive, we already have a TLD, so
+ // abort. If the return value is std::string::npos, there's no valid host,
+ // but we can try to append a TLD anyway, since the host may become valid once
+ // the TLD is attached -- for example, "999999999999" is detected as a broken
+ // IP address and marked invalid, but attaching ".com" makes it legal. When
+ // the return value is 0, there's a valid host with no known TLD, so we can
+ // definitely append the user's TLD. We disallow unknown registries here so
+ // users can input "mail.yahoo" and hit ctrl-enter to get
+ // "www.mail.yahoo.com".
+ const size_t registry_length =
+ net::registry_controlled_domains::GetRegistryLength(
+ *domain, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
+ net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
+ if ((registry_length != 0) && (registry_length != std::string::npos))
+ return;
+
+ // Add the suffix at the end of the domain.
+ const size_t domain_length(domain->length());
+ DCHECK_GT(domain_length, 0U);
+ DCHECK_NE(desired_tld[0], '.');
+ if ((*domain)[domain_length - 1] != '.')
+ domain->push_back('.');
+ domain->append(desired_tld);
+
+ // Now, if the domain begins with "www.", stop.
+ const std::string prefix("www.");
+ if (domain->compare(0, prefix.length(), prefix) != 0) {
+ // Otherwise, add www. to the beginning of the URL.
+ domain->insert(0, prefix);
+ }
+}
+
+inline void FixupUsername(const std::string& text,
+ const url::Component& part,
+ std::string* url) {
+ if (!part.is_valid())
+ return;
+
+ // We don't fix up the username at the moment.
+ url->append(text, part.begin, part.len);
+ // Do not append the trailing '@' because we might need to include the user's
+ // password. FixupURL itself will append the '@' for us.
+}
+
+inline void FixupPassword(const std::string& text,
+ const url::Component& part,
+ std::string* url) {
+ if (!part.is_valid())
+ return;
+
+ // We don't fix up the password at the moment.
+ url->append(":");
+ url->append(text, part.begin, part.len);
+}
+
+void FixupHost(const std::string& text,
+ const url::Component& part,
+ bool has_scheme,
+ const std::string& desired_tld,
+ std::string* url) {
+ if (!part.is_valid())
+ return;
+
+ // Make domain valid.
+ // Strip all leading dots and all but one trailing dot, unless the user only
+ // typed dots, in which case their input is totally invalid and we should just
+ // leave it unchanged.
+ std::string domain(text, part.begin, part.len);
+ const size_t first_nondot(domain.find_first_not_of('.'));
+ if (first_nondot != std::string::npos) {
+ domain.erase(0, first_nondot);
+ size_t last_nondot(domain.find_last_not_of('.'));
+ DCHECK(last_nondot != std::string::npos);
+ last_nondot += 2; // Point at second period in ending string
+ if (last_nondot < domain.length())
+ domain.erase(last_nondot);
+ }
+
+ // Add any user-specified TLD, if applicable.
+ AddDesiredTLD(desired_tld, &domain);
+
+ url->append(domain);
+}
+
+void FixupPort(const std::string& text,
+ const url::Component& part,
+ std::string* url) {
+ if (!part.is_valid())
+ return;
+
+ // We don't fix up the port at the moment.
+ url->append(":");
+ url->append(text, part.begin, part.len);
+}
+
+inline void FixupPath(const std::string& text,
+ const url::Component& part,
+ std::string* url) {
+ if (!part.is_valid() || part.len == 0) {
+ // We should always have a path.
+ url->append("/");
+ return;
+ }
+
+ // Append the path as is.
+ url->append(text, part.begin, part.len);
+}
+
+inline void FixupQuery(const std::string& text,
+ const url::Component& part,
+ std::string* url) {
+ if (!part.is_valid())
+ return;
+
+ // We don't fix up the query at the moment.
+ url->append("?");
+ url->append(text, part.begin, part.len);
+}
+
+inline void FixupRef(const std::string& text,
+ const url::Component& part,
+ std::string* url) {
+ if (!part.is_valid())
+ return;
+
+ // We don't fix up the ref at the moment.
+ url->append("#");
+ url->append(text, part.begin, part.len);
+}
+
+bool HasPort(const std::string& original_text,
+ const url::Component& scheme_component) {
+ // Find the range between the ":" and the "/".
+ size_t port_start = scheme_component.end() + 1;
+ size_t port_end = port_start;
+ while ((port_end < original_text.length()) &&
+ !url::IsAuthorityTerminator(original_text[port_end]))
+ ++port_end;
+ if (port_end == port_start)
+ return false;
+
+ // Scan the range to see if it is entirely digits.
+ for (size_t i = port_start; i < port_end; ++i) {
+ if (!base::IsAsciiDigit(original_text[i]))
+ return false;
+ }
+
+ return true;
+}
+
+// Try to extract a valid scheme from the beginning of |text|.
+// If successful, set |scheme_component| to the text range where the scheme
+// was located, and fill |canon_scheme| with its canonicalized form.
+// Otherwise, return false and leave the outputs in an indeterminate state.
+bool GetValidScheme(const std::string& text,
+ url::Component* scheme_component,
+ std::string* canon_scheme) {
+ canon_scheme->clear();
+
+ // Locate everything up to (but not including) the first ':'
+ if (!url::ExtractScheme(text.data(), static_cast<int>(text.length()),
+ scheme_component)) {
+ return false;
+ }
+
+ // Make sure the scheme contains only valid characters, and convert
+ // to lowercase. This also catches IPv6 literals like [::1], because
+ // brackets are not in the whitelist.
+ url::StdStringCanonOutput canon_scheme_output(canon_scheme);
+ url::Component canon_scheme_component;
+ if (!url::CanonicalizeScheme(text.data(), *scheme_component,
+ &canon_scheme_output, &canon_scheme_component)) {
+ return false;
+ }
+
+ // Strip the ':', and any trailing buffer space.
+ DCHECK_EQ(0, canon_scheme_component.begin);
+ canon_scheme->erase(canon_scheme_component.len);
+
+ // We need to fix up the segmentation for "www.example.com:/". For this
+ // case, we guess that schemes with a "." are not actually schemes.
+ if (canon_scheme->find('.') != std::string::npos)
+ return false;
+
+ // We need to fix up the segmentation for "www:123/". For this case, we
+ // will add an HTTP scheme later and make the URL parser happy.
+ // TODO(pkasting): Maybe we should try to use GURL's parser for this?
+ if (HasPort(text, *scheme_component))
+ return false;
+
+ // Everything checks out.
+ return true;
+}
+
+// Performs the work for url_formatter::SegmentURL. |text| may be modified on
+// output on success: a semicolon following a valid scheme is replaced with a
+// colon.
+std::string SegmentURLInternal(std::string* text, url::Parsed* parts) {
+ // Initialize the result.
+ *parts = url::Parsed();
+
+ std::string trimmed;
+ TrimWhitespaceUTF8(*text, base::TRIM_ALL, &trimmed);
+ if (trimmed.empty())
+ return std::string(); // Nothing to segment.
+
+#if defined(OS_WIN)
+ int trimmed_length = static_cast<int>(trimmed.length());
+ if (url::DoesBeginWindowsDriveSpec(trimmed.data(), 0, trimmed_length) ||
+ url::DoesBeginUNCPath(trimmed.data(), 0, trimmed_length, true))
+ return "file";
+#elif defined(OS_POSIX)
+ if (base::FilePath::IsSeparator(trimmed.data()[0]) ||
+ trimmed.data()[0] == '~')
+ return "file";
+#endif
+
+ // Otherwise, we need to look at things carefully.
+ std::string scheme;
+ if (!GetValidScheme(*text, &parts->scheme, &scheme)) {
+ // Try again if there is a ';' in the text. If changing it to a ':' results
+ // in a scheme being found, continue processing with the modified text.
+ bool found_scheme = false;
+ size_t semicolon = text->find(';');
+ if (semicolon != 0 && semicolon != std::string::npos) {
+ (*text)[semicolon] = ':';
+ if (GetValidScheme(*text, &parts->scheme, &scheme))
+ found_scheme = true;
+ else
+ (*text)[semicolon] = ';';
+ }
+ if (!found_scheme) {
+ // Couldn't determine the scheme, so just pick one.
+ parts->scheme.reset();
+ scheme =
+ base::StartsWith(*text, "ftp.", base::CompareCase::INSENSITIVE_ASCII)
+ ? url::kFtpScheme
+ : url::kHttpScheme;
+ }
+ }
+
+ // Proceed with about and chrome schemes, but not file or nonstandard schemes.
+ if ((scheme != url::kAboutScheme) && (scheme != kChromeUIScheme) &&
+ ((scheme == url::kFileScheme) ||
+ !url::IsStandard(
+ scheme.c_str(),
+ url::Component(0, static_cast<int>(scheme.length()))))) {
+ return scheme;
+ }
+
+ if (scheme == url::kFileSystemScheme) {
+ // Have the GURL parser do the heavy lifting for us.
+ url::ParseFileSystemURL(text->data(), static_cast<int>(text->length()),
+ parts);
+ return scheme;
+ }
+
+ if (parts->scheme.is_valid()) {
+ // Have the GURL parser do the heavy lifting for us.
+ url::ParseStandardURL(text->data(), static_cast<int>(text->length()),
+ parts);
+ return scheme;
+ }
+
+ // We need to add a scheme in order for ParseStandardURL to be happy.
+ // Find the first non-whitespace character.
+ std::string::iterator first_nonwhite = text->begin();
+ while ((first_nonwhite != text->end()) &&
+ base::IsUnicodeWhitespace(*first_nonwhite))
+ ++first_nonwhite;
+
+ // Construct the text to parse by inserting the scheme.
+ std::string inserted_text(scheme);
+ inserted_text.append(url::kStandardSchemeSeparator);
+ std::string text_to_parse(text->begin(), first_nonwhite);
+ text_to_parse.append(inserted_text);
+ text_to_parse.append(first_nonwhite, text->end());
+
+ // Have the GURL parser do the heavy lifting for us.
+ url::ParseStandardURL(text_to_parse.data(),
+ static_cast<int>(text_to_parse.length()), parts);
+
+ // Offset the results of the parse to match the original text.
+ const int offset = -static_cast<int>(inserted_text.length());
+ OffsetComponent(offset, &parts->scheme);
+ OffsetComponent(offset, &parts->username);
+ OffsetComponent(offset, &parts->password);
+ OffsetComponent(offset, &parts->host);
+ OffsetComponent(offset, &parts->port);
+ OffsetComponent(offset, &parts->path);
+ OffsetComponent(offset, &parts->query);
+ OffsetComponent(offset, &parts->ref);
+
+ return scheme;
+}
+
+} // namespace
+
+std::string SegmentURL(const std::string& text, url::Parsed* parts) {
+ std::string mutable_text(text);
+ return SegmentURLInternal(&mutable_text, parts);
+}
+
+base::string16 SegmentURL(const base::string16& text, url::Parsed* parts) {
+ std::string text_utf8 = base::UTF16ToUTF8(text);
+ url::Parsed parts_utf8;
+ std::string scheme_utf8 = SegmentURL(text_utf8, &parts_utf8);
+ UTF8PartsToUTF16Parts(text_utf8, parts_utf8, parts);
+ return base::UTF8ToUTF16(scheme_utf8);
+}
+
+GURL FixupURL(const std::string& text, const std::string& desired_tld) {
+ std::string trimmed;
+ TrimWhitespaceUTF8(text, base::TRIM_ALL, &trimmed);
+ if (trimmed.empty())
+ return GURL(); // Nothing here.
+
+ // Segment the URL.
+ url::Parsed parts;
+ std::string scheme(SegmentURLInternal(&trimmed, &parts));
+
+ // For view-source: URLs, we strip "view-source:", do fixup, and stick it back
+ // on. This allows us to handle things like "view-source:google.com".
+ if (scheme == kViewSourceScheme) {
+ // Reject "view-source:view-source:..." to avoid deep recursion.
+ std::string view_source(kViewSourceScheme + std::string(":"));
+ if (!base::StartsWith(text, view_source + view_source,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return GURL(kViewSourceScheme + std::string(":") +
+ FixupURL(trimmed.substr(scheme.length() + 1), desired_tld)
+ .possibly_invalid_spec());
+ }
+ }
+
+ // We handle the file scheme separately.
+ if (scheme == url::kFileScheme)
+ return GURL(parts.scheme.is_valid() ? text : FixupPath(text));
+
+ // We handle the filesystem scheme separately.
+ if (scheme == url::kFileSystemScheme) {
+ if (parts.inner_parsed() && parts.inner_parsed()->scheme.is_valid())
+ return GURL(text);
+ return GURL();
+ }
+
+ // Parse and rebuild about: and chrome: URLs, except about:blank.
+ bool chrome_url =
+ !base::LowerCaseEqualsASCII(trimmed, url::kAboutBlankURL) &&
+ ((scheme == url::kAboutScheme) || (scheme == kChromeUIScheme));
+
+ // For some schemes whose layouts we understand, we rebuild it.
+ if (chrome_url ||
+ url::IsStandard(scheme.c_str(),
+ url::Component(0, static_cast<int>(scheme.length())))) {
+ // Replace the about: scheme with the chrome: scheme.
+ std::string url(chrome_url ? kChromeUIScheme : scheme);
+ url.append(url::kStandardSchemeSeparator);
+
+ // We need to check whether the |username| is valid because it is our
+ // responsibility to append the '@' to delineate the user information from
+ // the host portion of the URL.
+ if (parts.username.is_valid()) {
+ FixupUsername(trimmed, parts.username, &url);
+ FixupPassword(trimmed, parts.password, &url);
+ url.append("@");
+ }
+
+ FixupHost(trimmed, parts.host, parts.scheme.is_valid(), desired_tld, &url);
+ if (chrome_url && !parts.host.is_valid())
+ url.append(kChromeUIDefaultHost);
+ FixupPort(trimmed, parts.port, &url);
+ FixupPath(trimmed, parts.path, &url);
+ FixupQuery(trimmed, parts.query, &url);
+ FixupRef(trimmed, parts.ref, &url);
+
+ return GURL(url);
+ }
+
+ // In the worst-case, we insert a scheme if the URL lacks one.
+ if (!parts.scheme.is_valid()) {
+ std::string fixed_scheme(scheme);
+ fixed_scheme.append(url::kStandardSchemeSeparator);
+ trimmed.insert(0, fixed_scheme);
+ }
+
+ return GURL(trimmed);
+}
+
+// The rules are different here than for regular fixup, since we need to handle
+// input like "hello.html" and know to look in the current directory. Regular
+// fixup will look for cues that it is actually a file path before trying to
+// figure out what file it is. If our logic doesn't work, we will fall back on
+// regular fixup.
+GURL FixupRelativeFile(const base::FilePath& base_dir,
+ const base::FilePath& text) {
+ base::FilePath old_cur_directory;
+ if (!base_dir.empty()) {
+ // Save the old current directory before we move to the new one.
+ base::GetCurrentDirectory(&old_cur_directory);
+ base::SetCurrentDirectory(base_dir);
+ }
+
+ // Allow funny input with extra whitespace and the wrong kind of slashes.
+ base::FilePath::StringType trimmed;
+ PrepareStringForFileOps(text, &trimmed);
+
+ bool is_file = true;
+ // Avoid recognizing definite non-file URLs as file paths.
+ GURL gurl(trimmed);
+ if (gurl.is_valid() && gurl.IsStandard())
+ is_file = false;
+ base::FilePath full_path;
+ if (is_file && !ValidPathForFile(trimmed, &full_path)) {
+// Not a path as entered, try unescaping it in case the user has
+// escaped things. We need to go through 8-bit since the escaped values
+// only represent 8-bit values.
+#if defined(OS_WIN)
+ std::wstring unescaped = base::UTF8ToWide(net::UnescapeURLComponent(
+ base::WideToUTF8(trimmed),
+ net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS));
+#elif defined(OS_POSIX)
+ std::string unescaped = net::UnescapeURLComponent(
+ trimmed,
+ net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS);
+#endif
+
+ if (!ValidPathForFile(unescaped, &full_path))
+ is_file = false;
+ }
+
+ // Put back the current directory if we saved it.
+ if (!base_dir.empty())
+ base::SetCurrentDirectory(old_cur_directory);
+
+ if (is_file) {
+ GURL file_url = net::FilePathToFileURL(full_path);
+ if (file_url.is_valid())
+ return GURL(base::UTF16ToUTF8(url_formatter::FormatUrl(
+ file_url, std::string(),
+ url_formatter::kFormatUrlOmitUsernamePassword,
+ net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr)));
+ // Invalid files fall through to regular processing.
+ }
+
+// Fall back on regular fixup for this input.
+#if defined(OS_WIN)
+ std::string text_utf8 = base::WideToUTF8(text.value());
+#elif defined(OS_POSIX)
+ std::string text_utf8 = text.value();
+#endif
+ return FixupURL(text_utf8, std::string());
+}
+
+void OffsetComponent(int offset, url::Component* part) {
+ DCHECK(part);
+
+ if (part->is_valid()) {
+ // Offset the location of this component.
+ part->begin += offset;
+
+ // This part might not have existed in the original text.
+ if (part->begin < 0)
+ part->reset();
+ }
+}
+
+bool IsEquivalentScheme(const std::string& scheme1,
+ const std::string& scheme2) {
+ return scheme1 == scheme2 ||
+ (scheme1 == url::kAboutScheme && scheme2 == kChromeUIScheme) ||
+ (scheme1 == kChromeUIScheme && scheme2 == url::kAboutScheme);
+}
+
+} // namespace url_formatter
diff --git a/chromium/components/url_formatter/url_fixer.h b/chromium/components/url_formatter/url_fixer.h
new file mode 100644
index 00000000000..b7c592d3940
--- /dev/null
+++ b/chromium/components/url_formatter/url_fixer.h
@@ -0,0 +1,87 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_URL_FORMATTER_URL_FIXER_H_
+#define COMPONENTS_URL_FORMATTER_URL_FIXER_H_
+
+#include <string>
+
+#include "base/strings/string16.h"
+#include "url/gurl.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace url {
+struct Component;
+struct Parsed;
+}
+
+// This object is designed to convert various types of input into URLs that we
+// know are valid. For example, user typing in the URL bar or command line
+// options. This is NOT the place for converting between different types of URLs
+// or parsing them, see net_util.h for that.
+namespace url_formatter {
+
+// Segments the given text string into parts of a URL. This is most useful for
+// schemes such as http, https, and ftp where |SegmentURL| will find many
+// segments. Currently does not segment "file" schemes.
+// Returns the canonicalized scheme, or the empty string when |text| is only
+// whitespace.
+std::string SegmentURL(const std::string& text, url::Parsed* parts);
+base::string16 SegmentURL(const base::string16& text, url::Parsed* parts);
+
+// Converts |text| to a fixed-up URL and returns it. Attempts to make some
+// "smart" adjustments to obviously-invalid input where possible.
+// |text| may be an absolute path to a file, which will get converted to a
+// "file:" URL.
+//
+// The result will be a "more" valid URL than the input. It may still not be
+// valid, so check the return value's validity or use possibly_invalid_spec().
+//
+// Schemes "about" and "chrome" are normalized to "chrome://", with slashes.
+// "about:blank" is unaltered, as Webkit allows frames to access about:blank.
+// Additionally, if a chrome URL does not have a valid host, as in "about:", the
+// returned URL will have the host "version", as in "chrome://version".
+//
+// If |desired_tld| is non-empty, it represents the TLD the user wishes to
+// append in the case of an incomplete domain. We check that this is not a file
+// path and there does not appear to be a valid TLD already, then append
+// |desired_tld| to the domain and prepend "www." (unless it, or a scheme, are
+// already present.) This TLD should not have a leading '.' (use "com" instead
+// of ".com").
+GURL FixupURL(const std::string& text, const std::string& desired_tld);
+
+// Converts |text| to a fixed-up URL, allowing it to be a relative path on the
+// local filesystem. Begin searching in |base_dir|; if empty, use the current
+// working directory. If this resolves to a file on disk, convert it to a
+// "file:" URL in |fixed_up_url|; otherwise, fall back to the behavior of
+// FixupURL().
+//
+// For "regular" input, even if it is possibly a file with a full path, you
+// should use FixupURL() directly. This function should only be used when
+// relative path handling is desired, as for command line processing.
+GURL FixupRelativeFile(const base::FilePath& base_dir,
+ const base::FilePath& text);
+
+// Offsets the beginning index of |part| by |offset|, which is allowed to be
+// negative. In some cases, the desired component does not exist at the given
+// offset. For example, when converting from "http://foo" to "foo", the scheme
+// component no longer exists. In such a case, the beginning index is set to 0.
+// Does nothing if |part| is invalid.
+void OffsetComponent(int offset, url::Component* part);
+
+// Returns true if |scheme1| is equivalent to |scheme2|.
+// Generally this is true if the two schemes are actually identical, but it's
+// also true when one scheme is "about" and the other "chrome".
+bool IsEquivalentScheme(const std::string& scheme1, const std::string& scheme2);
+
+// For paths like ~, we use $HOME for the current user's home directory.
+// For tests, we allow our idea of $HOME to be overriden by this variable.
+extern const char* home_directory_override;
+
+} // namespace url_formatter
+
+#endif // COMPONENTS_URL_FORMATTER_URL_FIXER_H_
diff --git a/chromium/components/url_formatter/url_fixer_unittest.cc b/chromium/components/url_formatter/url_fixer_unittest.cc
new file mode 100644
index 00000000000..900b553c39a
--- /dev/null
+++ b/chromium/components/url_formatter/url_fixer_unittest.cc
@@ -0,0 +1,537 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdlib.h>
+
+#include "base/base_paths.h"
+#include "base/basictypes.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/url_formatter/url_fixer.h"
+#include "net/base/filename_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/third_party/mozilla/url_parse.h"
+
+namespace url {
+
+std::ostream& operator<<(std::ostream& os, const Component& part) {
+ return os << "(begin=" << part.begin << ", len=" << part.len << ")";
+}
+
+} // namespace url
+
+struct SegmentCase {
+ const std::string input;
+ const std::string result;
+ const url::Component scheme;
+ const url::Component username;
+ const url::Component password;
+ const url::Component host;
+ const url::Component port;
+ const url::Component path;
+ const url::Component query;
+ const url::Component ref;
+};
+
+static const SegmentCase segment_cases[] = {
+ { "http://www.google.com/", "http",
+ url::Component(0, 4), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(7, 14), // host
+ url::Component(), // port
+ url::Component(21, 1), // path
+ url::Component(), // query
+ url::Component(), // ref
+ },
+ { "aBoUt:vErSiOn", "about",
+ url::Component(0, 5), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(6, 7), // host
+ url::Component(), // port
+ url::Component(), // path
+ url::Component(), // query
+ url::Component(), // ref
+ },
+ { "about:host/path?query#ref", "about",
+ url::Component(0, 5), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(6, 4), // host
+ url::Component(), // port
+ url::Component(10, 5), // path
+ url::Component(16, 5), // query
+ url::Component(22, 3), // ref
+ },
+ { "about://host/path?query#ref", "about",
+ url::Component(0, 5), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(8, 4), // host
+ url::Component(), // port
+ url::Component(12, 5), // path
+ url::Component(18, 5), // query
+ url::Component(24, 3), // ref
+ },
+ { "chrome:host/path?query#ref", "chrome",
+ url::Component(0, 6), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(7, 4), // host
+ url::Component(), // port
+ url::Component(11, 5), // path
+ url::Component(17, 5), // query
+ url::Component(23, 3), // ref
+ },
+ { "chrome://host/path?query#ref", "chrome",
+ url::Component(0, 6), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(9, 4), // host
+ url::Component(), // port
+ url::Component(13, 5), // path
+ url::Component(19, 5), // query
+ url::Component(25, 3), // ref
+ },
+ { " www.google.com:124?foo#", "http",
+ url::Component(), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(4, 14), // host
+ url::Component(19, 3), // port
+ url::Component(), // path
+ url::Component(23, 3), // query
+ url::Component(27, 0), // ref
+ },
+ { "user@www.google.com", "http",
+ url::Component(), // scheme
+ url::Component(0, 4), // username
+ url::Component(), // password
+ url::Component(5, 14), // host
+ url::Component(), // port
+ url::Component(), // path
+ url::Component(), // query
+ url::Component(), // ref
+ },
+ { "ftp:/user:P:a$$Wd@..ftp.google.com...::23///pub?foo#bar", "ftp",
+ url::Component(0, 3), // scheme
+ url::Component(5, 4), // username
+ url::Component(10, 7), // password
+ url::Component(18, 20), // host
+ url::Component(39, 2), // port
+ url::Component(41, 6), // path
+ url::Component(48, 3), // query
+ url::Component(52, 3), // ref
+ },
+ { "[2001:db8::1]/path", "http",
+ url::Component(), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(0, 13), // host
+ url::Component(), // port
+ url::Component(13, 5), // path
+ url::Component(), // query
+ url::Component(), // ref
+ },
+ { "[::1]", "http",
+ url::Component(), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(0, 5), // host
+ url::Component(), // port
+ url::Component(), // path
+ url::Component(), // query
+ url::Component(), // ref
+ },
+ // Incomplete IPv6 addresses (will not canonicalize).
+ { "[2001:4860:", "http",
+ url::Component(), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(0, 11), // host
+ url::Component(), // port
+ url::Component(), // path
+ url::Component(), // query
+ url::Component(), // ref
+ },
+ { "[2001:4860:/foo", "http",
+ url::Component(), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(0, 11), // host
+ url::Component(), // port
+ url::Component(11, 4), // path
+ url::Component(), // query
+ url::Component(), // ref
+ },
+ { "http://:b005::68]", "http",
+ url::Component(0, 4), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(7, 10), // host
+ url::Component(), // port
+ url::Component(), // path
+ url::Component(), // query
+ url::Component(), // ref
+ },
+ // Can't do anything useful with this.
+ { ":b005::68]", "",
+ url::Component(0, 0), // scheme
+ url::Component(), // username
+ url::Component(), // password
+ url::Component(), // host
+ url::Component(), // port
+ url::Component(), // path
+ url::Component(), // query
+ url::Component(), // ref
+ },
+};
+
+typedef testing::Test URLFixerTest;
+
+TEST(URLFixerTest, SegmentURL) {
+ std::string result;
+ url::Parsed parts;
+
+ for (size_t i = 0; i < arraysize(segment_cases); ++i) {
+ SegmentCase value = segment_cases[i];
+ result = url_formatter::SegmentURL(value.input, &parts);
+ EXPECT_EQ(value.result, result);
+ EXPECT_EQ(value.scheme, parts.scheme);
+ EXPECT_EQ(value.username, parts.username);
+ EXPECT_EQ(value.password, parts.password);
+ EXPECT_EQ(value.host, parts.host);
+ EXPECT_EQ(value.port, parts.port);
+ EXPECT_EQ(value.path, parts.path);
+ EXPECT_EQ(value.query, parts.query);
+ EXPECT_EQ(value.ref, parts.ref);
+ }
+}
+
+// Creates a file and returns its full name as well as the decomposed
+// version. Example:
+// full_path = "c:\foo\bar.txt"
+// dir = "c:\foo"
+// file_name = "bar.txt"
+static bool MakeTempFile(const base::FilePath& dir,
+ const base::FilePath& file_name,
+ base::FilePath* full_path) {
+ *full_path = dir.Append(file_name);
+ return base::WriteFile(*full_path, "", 0) == 0;
+}
+
+// Returns true if the given URL is a file: URL that matches the given file
+static bool IsMatchingFileURL(const std::string& url,
+ const base::FilePath& full_file_path) {
+ if (url.length() <= 8)
+ return false;
+ if (std::string("file:///") != url.substr(0, 8))
+ return false; // no file:/// prefix
+ if (url.find('\\') != std::string::npos)
+ return false; // contains backslashes
+
+ base::FilePath derived_path;
+ net::FileURLToFilePath(GURL(url), &derived_path);
+
+ return base::FilePath::CompareEqualIgnoreCase(derived_path.value(),
+ full_file_path.value());
+}
+
+struct FixupCase {
+ const std::string input;
+ const std::string output;
+} fixup_cases[] = {
+ {"www.google.com", "http://www.google.com/"},
+ {" www.google.com ", "http://www.google.com/"},
+ {" foo.com/asdf bar", "http://foo.com/asdf%20%20bar"},
+ {"..www.google.com..", "http://www.google.com./"},
+ {"http://......", "http://....../"},
+ {"http://host.com:ninety-two/", "http://host.com:ninety-two/"},
+ {"http://host.com:ninety-two?foo", "http://host.com:ninety-two/?foo"},
+ {"google.com:123", "http://google.com:123/"},
+ {"about:", "chrome://version/"},
+ {"about:foo", "chrome://foo/"},
+ {"about:version", "chrome://version/"},
+ {"about:blank", "about:blank"},
+ {"about:usr:pwd@hst/pth?qry#ref", "chrome://usr:pwd@hst/pth?qry#ref"},
+ {"about://usr:pwd@hst/pth?qry#ref", "chrome://usr:pwd@hst/pth?qry#ref"},
+ {"chrome:usr:pwd@hst/pth?qry#ref", "chrome://usr:pwd@hst/pth?qry#ref"},
+ {"chrome://usr:pwd@hst/pth?qry#ref", "chrome://usr:pwd@hst/pth?qry#ref"},
+ {"www:123", "http://www:123/"},
+ {" www:123", "http://www:123/"},
+ {"www.google.com?foo", "http://www.google.com/?foo"},
+ {"www.google.com#foo", "http://www.google.com/#foo"},
+ {"www.google.com?", "http://www.google.com/?"},
+ {"www.google.com#", "http://www.google.com/#"},
+ {"www.google.com:123?foo#bar", "http://www.google.com:123/?foo#bar"},
+ {"user@www.google.com", "http://user@www.google.com/"},
+ {"\xE6\xB0\xB4.com", "http://xn--1rw.com/"},
+ // It would be better if this next case got treated as http, but I don't see
+ // a clean way to guess this isn't the new-and-exciting "user" scheme.
+ {"user:passwd@www.google.com:8080/", "user:passwd@www.google.com:8080/"},
+ // {"file:///c:/foo/bar%20baz.txt", "file:///C:/foo/bar%20baz.txt"},
+ {"ftp.google.com", "ftp://ftp.google.com/"},
+ {" ftp.google.com", "ftp://ftp.google.com/"},
+ {"FTP.GooGle.com", "ftp://ftp.google.com/"},
+ {"ftpblah.google.com", "http://ftpblah.google.com/"},
+ {"ftp", "http://ftp/"},
+ {"google.ftp.com", "http://google.ftp.com/"},
+ // URLs which end with 0x85 (NEL in ISO-8859).
+ {"http://foo.com/s?q=\xd0\x85", "http://foo.com/s?q=%D0%85"},
+ {"http://foo.com/s?q=\xec\x97\x85", "http://foo.com/s?q=%EC%97%85"},
+ {"http://foo.com/s?q=\xf0\x90\x80\x85", "http://foo.com/s?q=%F0%90%80%85"},
+ // URLs which end with 0xA0 (non-break space in ISO-8859).
+ {"http://foo.com/s?q=\xd0\xa0", "http://foo.com/s?q=%D0%A0"},
+ {"http://foo.com/s?q=\xec\x97\xa0", "http://foo.com/s?q=%EC%97%A0"},
+ {"http://foo.com/s?q=\xf0\x90\x80\xa0", "http://foo.com/s?q=%F0%90%80%A0"},
+ // URLs containing IPv6 literals.
+ {"[2001:db8::2]", "http://[2001:db8::2]/"},
+ {"[::]:80", "http://[::]/"},
+ {"[::]:80/path", "http://[::]/path"},
+ {"[::]:180/path", "http://[::]:180/path"},
+ // TODO(pmarks): Maybe we should parse bare IPv6 literals someday.
+ {"::1", "::1"},
+ // Semicolon as scheme separator for standard schemes.
+ {"http;//www.google.com/", "http://www.google.com/"},
+ {"about;chrome", "chrome://chrome/"},
+ // Semicolon left as-is for non-standard schemes.
+ {"whatsup;//fool", "whatsup://fool"},
+ // Semicolon left as-is in URL itself.
+ {"http://host/port?query;moar", "http://host/port?query;moar"},
+ // Fewer slashes than expected.
+ {"http;www.google.com/", "http://www.google.com/"},
+ {"http;/www.google.com/", "http://www.google.com/"},
+ // Semicolon at start.
+ {";http://www.google.com/", "http://%3Bhttp//www.google.com/"},
+};
+
+TEST(URLFixerTest, FixupURL) {
+ for (size_t i = 0; i < arraysize(fixup_cases); ++i) {
+ FixupCase value = fixup_cases[i];
+ EXPECT_EQ(value.output,
+ url_formatter::FixupURL(value.input, "").possibly_invalid_spec())
+ << "input: " << value.input;
+ }
+
+ // Check the TLD-appending functionality.
+ FixupCase tld_cases[] = {
+ {"somedomainthatwillnotbeagtld",
+ "http://www.somedomainthatwillnotbeagtld.com/"},
+ {"somedomainthatwillnotbeagtld.",
+ "http://www.somedomainthatwillnotbeagtld.com/"},
+ {"somedomainthatwillnotbeagtld..",
+ "http://www.somedomainthatwillnotbeagtld.com/"},
+ {".somedomainthatwillnotbeagtld",
+ "http://www.somedomainthatwillnotbeagtld.com/"},
+ {"www.somedomainthatwillnotbeagtld",
+ "http://www.somedomainthatwillnotbeagtld.com/"},
+ {"somedomainthatwillnotbeagtld.com",
+ "http://somedomainthatwillnotbeagtld.com/"},
+ {"http://somedomainthatwillnotbeagtld",
+ "http://www.somedomainthatwillnotbeagtld.com/"},
+ {"..somedomainthatwillnotbeagtld..",
+ "http://www.somedomainthatwillnotbeagtld.com/"},
+ {"http://www.somedomainthatwillnotbeagtld",
+ "http://www.somedomainthatwillnotbeagtld.com/"},
+ {"9999999999999999", "http://www.9999999999999999.com/"},
+ {"somedomainthatwillnotbeagtld/foo",
+ "http://www.somedomainthatwillnotbeagtld.com/foo"},
+ {"somedomainthatwillnotbeagtld.com/foo",
+ "http://somedomainthatwillnotbeagtld.com/foo"},
+ {"somedomainthatwillnotbeagtld/?foo=.com",
+ "http://www.somedomainthatwillnotbeagtld.com/?foo=.com"},
+ {"www.somedomainthatwillnotbeagtld/?foo=www.",
+ "http://www.somedomainthatwillnotbeagtld.com/?foo=www."},
+ {"somedomainthatwillnotbeagtld.com/?foo=.com",
+ "http://somedomainthatwillnotbeagtld.com/?foo=.com"},
+ {"http://www.somedomainthatwillnotbeagtld.com",
+ "http://www.somedomainthatwillnotbeagtld.com/"},
+ {"somedomainthatwillnotbeagtld:123",
+ "http://www.somedomainthatwillnotbeagtld.com:123/"},
+ {"http://somedomainthatwillnotbeagtld:123",
+ "http://www.somedomainthatwillnotbeagtld.com:123/"},
+ };
+ for (size_t i = 0; i < arraysize(tld_cases); ++i) {
+ FixupCase value = tld_cases[i];
+ EXPECT_EQ(value.output, url_formatter::FixupURL(value.input, "com")
+ .possibly_invalid_spec());
+ }
+}
+
+// Test different types of file inputs to URIFixerUpper::FixupURL. This
+// doesn't go into the nice array of fixups above since the file input
+// has to exist.
+TEST(URLFixerTest, FixupFile) {
+ // this "original" filename is the one we tweak to get all the variations
+ base::ScopedTempDir temp_dir_;
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ base::FilePath original;
+ ASSERT_TRUE(MakeTempFile(
+ temp_dir_.path(),
+ base::FilePath(FILE_PATH_LITERAL("url fixer upper existing file.txt")),
+ &original));
+
+ // reference path
+ GURL golden(net::FilePathToFileURL(original));
+
+ // c:\foo\bar.txt -> file:///c:/foo/bar.txt (basic)
+ GURL fixedup(url_formatter::FixupURL(original.AsUTF8Unsafe(), std::string()));
+ EXPECT_EQ(golden, fixedup);
+
+ // TODO(port): Make some equivalent tests for posix.
+#if defined(OS_WIN)
+ // c|/foo\bar.txt -> file:///c:/foo/bar.txt (pipe allowed instead of colon)
+ std::string cur(base::WideToUTF8(original.value()));
+ EXPECT_EQ(':', cur[1]);
+ cur[1] = '|';
+ EXPECT_EQ(golden, url_formatter::FixupURL(cur, std::string()));
+
+ FixupCase cases[] = {
+ {"c:\\Non-existent%20file.txt", "file:///C:/Non-existent%2520file.txt"},
+
+ // \\foo\bar.txt -> file://foo/bar.txt
+ // UNC paths, this file won't exist, but since there are no escapes, it
+ // should be returned just converted to a file: URL.
+ {"\\\\NonexistentHost\\foo\\bar.txt", "file://nonexistenthost/foo/bar.txt"},
+ // We do this strictly, like IE8, which only accepts this form using
+ // backslashes and not forward ones. Turning "//foo" into "http" matches
+ // Firefox and IE, silly though it may seem (it falls out of adding "http"
+ // as the default protocol if you haven't entered one).
+ {"//NonexistentHost\\foo/bar.txt", "http://nonexistenthost/foo/bar.txt"},
+ {"file:///C:/foo/bar", "file:///C:/foo/bar"},
+
+ // Much of the work here comes from GURL's canonicalization stage.
+ {"file://C:/foo/bar", "file:///C:/foo/bar"},
+ {"file:c:", "file:///C:/"},
+ {"file:c:WINDOWS", "file:///C:/WINDOWS"},
+ {"file:c|Program Files", "file:///C:/Program%20Files"},
+ {"file:/file", "file://file/"},
+ {"file:////////c:\\foo", "file:///C:/foo"},
+ {"file://server/folder/file", "file://server/folder/file"},
+
+ // These are fixups we don't do, but could consider:
+ // {"file:///foo:/bar", "file://foo/bar"},
+ // {"file:/\\/server\\folder/file", "file://server/folder/file"},
+ };
+#elif defined(OS_POSIX)
+
+#if defined(OS_MACOSX)
+#define HOME "/Users/"
+#else
+#define HOME "/home/"
+#endif
+ url_formatter::home_directory_override = "/foo";
+ FixupCase cases[] = {
+ // File URLs go through GURL, which tries to escape intelligently.
+ {"/A%20non-existent file.txt", "file:///A%2520non-existent%20file.txt"},
+ // A plain "/" refers to the root.
+ {"/", "file:///"},
+
+ // These rely on the above home_directory_override.
+ {"~", "file:///foo"},
+ {"~/bar", "file:///foo/bar"},
+
+ // References to other users' homedirs.
+ {"~foo", "file://" HOME "foo"},
+ {"~x/blah", "file://" HOME "x/blah"},
+ };
+#endif
+
+ for (size_t i = 0; i < arraysize(cases); i++) {
+ EXPECT_EQ(cases[i].output,
+ url_formatter::FixupURL(cases[i].input, std::string())
+ .possibly_invalid_spec());
+ }
+
+ EXPECT_TRUE(base::DeleteFile(original, false));
+}
+
+TEST(URLFixerTest, FixupRelativeFile) {
+ base::FilePath full_path;
+ base::FilePath file_part(
+ FILE_PATH_LITERAL("url_fixer_upper_existing_file.txt"));
+ base::ScopedTempDir temp_dir_;
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ASSERT_TRUE(MakeTempFile(temp_dir_.path(), file_part, &full_path));
+ full_path = base::MakeAbsoluteFilePath(full_path);
+ ASSERT_FALSE(full_path.empty());
+
+ // make sure we pass through good URLs
+ for (size_t i = 0; i < arraysize(fixup_cases); ++i) {
+ FixupCase value = fixup_cases[i];
+ base::FilePath input = base::FilePath::FromUTF8Unsafe(value.input);
+ EXPECT_EQ(value.output,
+ url_formatter::FixupRelativeFile(temp_dir_.path(),
+ input).possibly_invalid_spec());
+ }
+
+ // make sure the existing file got fixed-up to a file URL, and that there
+ // are no backslashes
+ EXPECT_TRUE(IsMatchingFileURL(
+ url_formatter::FixupRelativeFile(temp_dir_.path(),
+ file_part).possibly_invalid_spec(), full_path));
+ EXPECT_TRUE(base::DeleteFile(full_path, false));
+
+ // create a filename we know doesn't exist and make sure it doesn't get
+ // fixed up to a file URL
+ base::FilePath nonexistent_file(
+ FILE_PATH_LITERAL("url_fixer_upper_nonexistent_file.txt"));
+ std::string fixedup(url_formatter::FixupRelativeFile(
+ temp_dir_.path(), nonexistent_file).possibly_invalid_spec());
+ EXPECT_NE(std::string("file:///"), fixedup.substr(0, 8));
+ EXPECT_FALSE(IsMatchingFileURL(fixedup, nonexistent_file));
+
+ // make a subdir to make sure relative paths with directories work, also
+ // test spaces:
+ // "app_dir\url fixer-upper dir\url fixer-upper existing file.txt"
+ base::FilePath sub_dir(FILE_PATH_LITERAL("url fixer-upper dir"));
+ base::FilePath sub_file(
+ FILE_PATH_LITERAL("url fixer-upper existing file.txt"));
+ base::FilePath new_dir = temp_dir_.path().Append(sub_dir);
+ base::CreateDirectory(new_dir);
+ ASSERT_TRUE(MakeTempFile(new_dir, sub_file, &full_path));
+ full_path = base::MakeAbsoluteFilePath(full_path);
+ ASSERT_FALSE(full_path.empty());
+
+ // test file in the subdir
+ base::FilePath relative_file = sub_dir.Append(sub_file);
+ EXPECT_TRUE(IsMatchingFileURL(
+ url_formatter::FixupRelativeFile(temp_dir_.path(),
+ relative_file).possibly_invalid_spec(), full_path));
+
+ // test file in the subdir with different slashes and escaping.
+ base::FilePath::StringType relative_file_str = sub_dir.value() +
+ FILE_PATH_LITERAL("/") + sub_file.value();
+ base::ReplaceSubstringsAfterOffset(&relative_file_str, 0,
+ FILE_PATH_LITERAL(" "), FILE_PATH_LITERAL("%20"));
+ EXPECT_TRUE(IsMatchingFileURL(
+ url_formatter::FixupRelativeFile(temp_dir_.path(),
+ base::FilePath(relative_file_str)).possibly_invalid_spec(),
+ full_path));
+
+ // test relative directories and duplicate slashes
+ // (should resolve to the same file as above)
+ relative_file_str = sub_dir.value() + FILE_PATH_LITERAL("/../") +
+ sub_dir.value() + FILE_PATH_LITERAL("///./") + sub_file.value();
+ EXPECT_TRUE(IsMatchingFileURL(
+ url_formatter::FixupRelativeFile(temp_dir_.path(),
+ base::FilePath(relative_file_str)).possibly_invalid_spec(),
+ full_path));
+
+ // done with the subdir
+ EXPECT_TRUE(base::DeleteFile(full_path, false));
+ EXPECT_TRUE(base::DeleteFile(new_dir, true));
+
+ // Test that an obvious HTTP URL isn't accidentally treated as an absolute
+ // file path (on account of system-specific craziness).
+ base::FilePath empty_path;
+ base::FilePath http_url_path(FILE_PATH_LITERAL("http://../"));
+ EXPECT_TRUE(url_formatter::FixupRelativeFile(empty_path, http_url_path)
+ .SchemeIs("http"));
+}
diff --git a/chromium/components/url_formatter/url_formatter.cc b/chromium/components/url_formatter/url_formatter.cc
new file mode 100644
index 00000000000..ac7c62e14c7
--- /dev/null
+++ b/chromium/components/url_formatter/url_formatter.cc
@@ -0,0 +1,807 @@
+// 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/url_formatter/url_formatter.h"
+
+#include <algorithm>
+#include <map>
+#include <utility>
+
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "base/stl_util.h"
+#include "base/strings/string_tokenizer.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_offset_string_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/lock.h"
+#include "third_party/icu/source/common/unicode/uidna.h"
+#include "third_party/icu/source/common/unicode/uniset.h"
+#include "third_party/icu/source/common/unicode/uscript.h"
+#include "third_party/icu/source/i18n/unicode/regex.h"
+#include "third_party/icu/source/i18n/unicode/ulocdata.h"
+#include "url/gurl.h"
+#include "url/third_party/mozilla/url_parse.h"
+
+namespace url_formatter {
+
+namespace {
+
+base::string16 IDNToUnicodeWithAdjustments(
+ const std::string& host,
+ const std::string& languages,
+ base::OffsetAdjuster::Adjustments* adjustments);
+bool IDNToUnicodeOneComponent(const base::char16* comp,
+ size_t comp_len,
+ const std::string& languages,
+ base::string16* out);
+
+class AppendComponentTransform {
+ public:
+ AppendComponentTransform() {}
+ virtual ~AppendComponentTransform() {}
+
+ virtual base::string16 Execute(
+ const std::string& component_text,
+ base::OffsetAdjuster::Adjustments* adjustments) const = 0;
+
+ // NOTE: No DISALLOW_COPY_AND_ASSIGN here, since gcc < 4.3.0 requires an
+ // accessible copy constructor in order to call AppendFormattedComponent()
+ // with an inline temporary (see http://gcc.gnu.org/bugs/#cxx%5Frvalbind ).
+};
+
+class HostComponentTransform : public AppendComponentTransform {
+ public:
+ explicit HostComponentTransform(const std::string& languages)
+ : languages_(languages) {}
+
+ private:
+ base::string16 Execute(
+ const std::string& component_text,
+ base::OffsetAdjuster::Adjustments* adjustments) const override {
+ return IDNToUnicodeWithAdjustments(component_text, languages_, adjustments);
+ }
+
+ const std::string& languages_;
+};
+
+class NonHostComponentTransform : public AppendComponentTransform {
+ public:
+ explicit NonHostComponentTransform(net::UnescapeRule::Type unescape_rules)
+ : unescape_rules_(unescape_rules) {}
+
+ private:
+ base::string16 Execute(
+ const std::string& component_text,
+ base::OffsetAdjuster::Adjustments* adjustments) const override {
+ return (unescape_rules_ == net::UnescapeRule::NONE)
+ ? base::UTF8ToUTF16WithAdjustments(component_text, adjustments)
+ : net::UnescapeAndDecodeUTF8URLComponentWithAdjustments(
+ component_text, unescape_rules_, adjustments);
+ }
+
+ const net::UnescapeRule::Type unescape_rules_;
+};
+
+// Transforms the portion of |spec| covered by |original_component| according to
+// |transform|. Appends the result to |output|. If |output_component| is
+// non-NULL, its start and length are set to the transformed component's new
+// start and length. If |adjustments| is non-NULL, appends adjustments (if
+// any) that reflect the transformation the original component underwent to
+// become the transformed value appended to |output|.
+void AppendFormattedComponent(const std::string& spec,
+ const url::Component& original_component,
+ const AppendComponentTransform& transform,
+ base::string16* output,
+ url::Component* output_component,
+ base::OffsetAdjuster::Adjustments* adjustments) {
+ DCHECK(output);
+ if (original_component.is_nonempty()) {
+ size_t original_component_begin =
+ static_cast<size_t>(original_component.begin);
+ size_t output_component_begin = output->length();
+ std::string component_str(spec, original_component_begin,
+ static_cast<size_t>(original_component.len));
+
+ // Transform |component_str| and modify |adjustments| appropriately.
+ base::OffsetAdjuster::Adjustments component_transform_adjustments;
+ output->append(
+ transform.Execute(component_str, &component_transform_adjustments));
+
+ // Shift all the adjustments made for this component so the offsets are
+ // valid for the original string and add them to |adjustments|.
+ for (base::OffsetAdjuster::Adjustments::iterator comp_iter =
+ component_transform_adjustments.begin();
+ comp_iter != component_transform_adjustments.end(); ++comp_iter)
+ comp_iter->original_offset += original_component_begin;
+ if (adjustments) {
+ adjustments->insert(adjustments->end(),
+ component_transform_adjustments.begin(),
+ component_transform_adjustments.end());
+ }
+
+ // Set positions of the parsed component.
+ if (output_component) {
+ output_component->begin = static_cast<int>(output_component_begin);
+ output_component->len =
+ static_cast<int>(output->length() - output_component_begin);
+ }
+ } else if (output_component) {
+ output_component->reset();
+ }
+}
+
+// If |component| is valid, its begin is incremented by |delta|.
+void AdjustComponent(int delta, url::Component* component) {
+ if (!component->is_valid())
+ return;
+
+ DCHECK(delta >= 0 || component->begin >= -delta);
+ component->begin += delta;
+}
+
+// Adjusts all the components of |parsed| by |delta|, except for the scheme.
+void AdjustAllComponentsButScheme(int delta, url::Parsed* parsed) {
+ AdjustComponent(delta, &(parsed->username));
+ AdjustComponent(delta, &(parsed->password));
+ AdjustComponent(delta, &(parsed->host));
+ AdjustComponent(delta, &(parsed->port));
+ AdjustComponent(delta, &(parsed->path));
+ AdjustComponent(delta, &(parsed->query));
+ AdjustComponent(delta, &(parsed->ref));
+}
+
+// Helper for FormatUrlWithOffsets().
+base::string16 FormatViewSourceUrl(
+ const GURL& url,
+ const std::string& languages,
+ FormatUrlTypes format_types,
+ net::UnescapeRule::Type unescape_rules,
+ url::Parsed* new_parsed,
+ size_t* prefix_end,
+ base::OffsetAdjuster::Adjustments* adjustments) {
+ DCHECK(new_parsed);
+ const char kViewSource[] = "view-source:";
+ const size_t kViewSourceLength = arraysize(kViewSource) - 1;
+
+ // Format the underlying URL and record adjustments.
+ const std::string& url_str(url.possibly_invalid_spec());
+ adjustments->clear();
+ base::string16 result(
+ base::ASCIIToUTF16(kViewSource) +
+ FormatUrlWithAdjustments(GURL(url_str.substr(kViewSourceLength)),
+ languages, format_types, unescape_rules,
+ new_parsed, prefix_end, adjustments));
+ // Revise |adjustments| by shifting to the offsets to prefix that the above
+ // call to FormatUrl didn't get to see.
+ for (base::OffsetAdjuster::Adjustments::iterator it = adjustments->begin();
+ it != adjustments->end(); ++it)
+ it->original_offset += kViewSourceLength;
+
+ // Adjust positions of the parsed components.
+ if (new_parsed->scheme.is_nonempty()) {
+ // Assume "view-source:real-scheme" as a scheme.
+ new_parsed->scheme.len += kViewSourceLength;
+ } else {
+ new_parsed->scheme.begin = 0;
+ new_parsed->scheme.len = kViewSourceLength - 1;
+ }
+ AdjustAllComponentsButScheme(kViewSourceLength, new_parsed);
+
+ if (prefix_end)
+ *prefix_end += kViewSourceLength;
+
+ return result;
+}
+
+// TODO(brettw) bug 734373: check the scripts for each host component and
+// don't un-IDN-ize if there is more than one. Alternatively, only IDN for
+// scripts that the user has installed. For now, just put the entire
+// path through IDN. Maybe this feature can be implemented in ICU itself?
+//
+// We may want to skip this step in the case of file URLs to allow unicode
+// UNC hostnames regardless of encodings.
+base::string16 IDNToUnicodeWithAdjustments(
+ const std::string& host,
+ const std::string& languages,
+ base::OffsetAdjuster::Adjustments* adjustments) {
+ if (adjustments)
+ adjustments->clear();
+ // Convert the ASCII input to a base::string16 for ICU.
+ base::string16 input16;
+ input16.reserve(host.length());
+ input16.insert(input16.end(), host.begin(), host.end());
+
+ // Do each component of the host separately, since we enforce script matching
+ // on a per-component basis.
+ base::string16 out16;
+ for (size_t component_start = 0, component_end;
+ component_start < input16.length();
+ component_start = component_end + 1) {
+ // Find the end of the component.
+ component_end = input16.find('.', component_start);
+ if (component_end == base::string16::npos)
+ component_end = input16.length(); // For getting the last component.
+ size_t component_length = component_end - component_start;
+ size_t new_component_start = out16.length();
+ bool converted_idn = false;
+ if (component_end > component_start) {
+ // Add the substring that we just found.
+ converted_idn =
+ IDNToUnicodeOneComponent(input16.data() + component_start,
+ component_length, languages, &out16);
+ }
+ size_t new_component_length = out16.length() - new_component_start;
+
+ if (converted_idn && adjustments) {
+ adjustments->push_back(base::OffsetAdjuster::Adjustment(
+ component_start, component_length, new_component_length));
+ }
+
+ // Need to add the dot we just found (if we found one).
+ if (component_end < input16.length())
+ out16.push_back('.');
+ }
+ return out16;
+}
+
+// Does some simple normalization of scripts so we can allow certain scripts
+// to exist together.
+// TODO(brettw) bug 880223: we should allow some other languages to be
+// oombined such as Chinese and Latin. We will probably need a more
+// complicated system of language pairs to have more fine-grained control.
+UScriptCode NormalizeScript(UScriptCode code) {
+ switch (code) {
+ case USCRIPT_KATAKANA:
+ case USCRIPT_HIRAGANA:
+ case USCRIPT_KATAKANA_OR_HIRAGANA:
+ case USCRIPT_HANGUL: // This one is arguable.
+ return USCRIPT_HAN;
+ default:
+ return code;
+ }
+}
+
+bool IsIDNComponentInSingleScript(const base::char16* str, int str_len) {
+ UScriptCode first_script = USCRIPT_INVALID_CODE;
+ bool is_first = true;
+
+ int i = 0;
+ while (i < str_len) {
+ unsigned code_point;
+ U16_NEXT(str, i, str_len, code_point);
+
+ UErrorCode err = U_ZERO_ERROR;
+ UScriptCode cur_script = uscript_getScript(code_point, &err);
+ if (err != U_ZERO_ERROR)
+ return false; // Report mixed on error.
+ cur_script = NormalizeScript(cur_script);
+
+ // TODO(brettw) We may have to check for USCRIPT_INHERENT as well.
+ if (is_first && cur_script != USCRIPT_COMMON) {
+ first_script = cur_script;
+ is_first = false;
+ } else {
+ if (cur_script != USCRIPT_COMMON && cur_script != first_script)
+ return false;
+ }
+ }
+ return true;
+}
+
+// Check if the script of a language can be 'safely' mixed with
+// Latin letters in the ASCII range.
+bool IsCompatibleWithASCIILetters(const std::string& lang) {
+ // For now, just list Chinese, Japanese and Korean (positive list).
+ // An alternative is negative-listing (languages using Greek and
+ // Cyrillic letters), but it can be more dangerous.
+ return !lang.substr(0, 2).compare("zh") || !lang.substr(0, 2).compare("ja") ||
+ !lang.substr(0, 2).compare("ko");
+}
+
+typedef std::map<std::string, icu::UnicodeSet*> LangToExemplarSetMap;
+
+class LangToExemplarSet {
+ public:
+ static LangToExemplarSet* GetInstance() {
+ return base::Singleton<LangToExemplarSet>::get();
+ }
+
+ private:
+ LangToExemplarSetMap map;
+ LangToExemplarSet() {}
+ ~LangToExemplarSet() {
+ STLDeleteContainerPairSecondPointers(map.begin(), map.end());
+ }
+
+ friend class base::Singleton<LangToExemplarSet>;
+ friend struct base::DefaultSingletonTraits<LangToExemplarSet>;
+ friend bool GetExemplarSetForLang(const std::string&, icu::UnicodeSet**);
+ friend void SetExemplarSetForLang(const std::string&, icu::UnicodeSet*);
+
+ DISALLOW_COPY_AND_ASSIGN(LangToExemplarSet);
+};
+
+bool GetExemplarSetForLang(const std::string& lang,
+ icu::UnicodeSet** lang_set) {
+ const LangToExemplarSetMap& map = LangToExemplarSet::GetInstance()->map;
+ LangToExemplarSetMap::const_iterator pos = map.find(lang);
+ if (pos != map.end()) {
+ *lang_set = pos->second;
+ return true;
+ }
+ return false;
+}
+
+void SetExemplarSetForLang(const std::string& lang, icu::UnicodeSet* lang_set) {
+ LangToExemplarSetMap& map = LangToExemplarSet::GetInstance()->map;
+ map.insert(std::make_pair(lang, lang_set));
+}
+
+static base::LazyInstance<base::Lock>::Leaky g_lang_set_lock =
+ LAZY_INSTANCE_INITIALIZER;
+
+// Returns true if all the characters in component_characters are used by
+// the language |lang|.
+bool IsComponentCoveredByLang(const icu::UnicodeSet& component_characters,
+ const std::string& lang) {
+ CR_DEFINE_STATIC_LOCAL(const icu::UnicodeSet, kASCIILetters, ('a', 'z'));
+ icu::UnicodeSet* lang_set = nullptr;
+ // We're called from both the UI thread and the history thread.
+ {
+ base::AutoLock lock(g_lang_set_lock.Get());
+ if (!GetExemplarSetForLang(lang, &lang_set)) {
+ UErrorCode status = U_ZERO_ERROR;
+ ULocaleData* uld = ulocdata_open(lang.c_str(), &status);
+ // TODO(jungshik) Turn this check on when the ICU data file is
+ // rebuilt with the minimal subset of locale data for languages
+ // to which Chrome is not localized but which we offer in the list
+ // of languages selectable for Accept-Languages. With the rebuilt ICU
+ // data, ulocdata_open never should fall back to the default locale.
+ // (issue 2078)
+ // DCHECK(U_SUCCESS(status) && status != U_USING_DEFAULT_WARNING);
+ if (U_SUCCESS(status) && status != U_USING_DEFAULT_WARNING) {
+ lang_set = reinterpret_cast<icu::UnicodeSet*>(ulocdata_getExemplarSet(
+ uld, nullptr, 0, ULOCDATA_ES_STANDARD, &status));
+ // On success, if |lang| is compatible with ASCII Latin letters, add
+ // them.
+ if (lang_set && IsCompatibleWithASCIILetters(lang))
+ lang_set->addAll(kASCIILetters);
+ }
+
+ if (!lang_set)
+ lang_set = new icu::UnicodeSet(1, 0);
+
+ lang_set->freeze();
+ SetExemplarSetForLang(lang, lang_set);
+ ulocdata_close(uld);
+ }
+ }
+ return !lang_set->isEmpty() && lang_set->containsAll(component_characters);
+}
+
+// Returns true if the given Unicode host component is safe to display to the
+// user.
+bool IsIDNComponentSafe(const base::char16* str,
+ int str_len,
+ const std::string& languages) {
+ // Most common cases (non-IDN) do not reach here so that we don't
+ // need a fast return path.
+ // TODO(jungshik) : Check if there's any character inappropriate
+ // (although allowed) for domain names.
+ // See http://www.unicode.org/reports/tr39/#IDN_Security_Profiles and
+ // http://www.unicode.org/reports/tr39/data/xidmodifications.txt
+ // For now, we borrow the list from Mozilla and tweaked it slightly.
+ // (e.g. Characters like U+00A0, U+3000, U+3002 are omitted because
+ // they're gonna be canonicalized to U+0020 and full stop before
+ // reaching here.)
+ // The original list is available at
+ // http://kb.mozillazine.org/Network.IDN.blacklist_chars and
+ // at
+ // http://mxr.mozilla.org/seamonkey/source/modules/libpref/src/init/all.js#703
+
+ UErrorCode status = U_ZERO_ERROR;
+#ifdef U_WCHAR_IS_UTF16
+ icu::UnicodeSet dangerous_characters(
+ icu::UnicodeString(
+ L"[[\\ \u00ad\u00bc\u00bd\u01c3\u0337\u0338"
+ L"\u05c3\u05f4\u06d4\u0702\u115f\u1160][\u2000-\u200b]"
+ L"[\u2024\u2027\u2028\u2029\u2039\u203a\u2044\u205f]"
+ L"[\u2154-\u2156][\u2159-\u215b][\u215f\u2215\u23ae"
+ L"\u29f6\u29f8\u2afb\u2afd][\u2ff0-\u2ffb][\u3014"
+ L"\u3015\u3033\u3164\u321d\u321e\u33ae\u33af\u33c6\u33df\ufe14"
+ L"\ufe15\ufe3f\ufe5d\ufe5e\ufeff\uff0e\uff06\uff61\uffa0\ufff9]"
+ L"[\ufffa-\ufffd]\U0001f50f\U0001f510\U0001f512\U0001f513]"),
+ status);
+ DCHECK(U_SUCCESS(status));
+ icu::RegexMatcher dangerous_patterns(
+ icu::UnicodeString(
+ // Lone katakana no, so, or n
+ L"[^\\p{Katakana}][\u30ce\u30f3\u30bd][^\\p{Katakana}]"
+ // Repeating Japanese accent characters
+ L"|[\u3099\u309a\u309b\u309c][\u3099\u309a\u309b\u309c]"),
+ 0, status);
+#else
+ icu::UnicodeSet dangerous_characters(
+ icu::UnicodeString(
+ "[[\\u0020\\u00ad\\u00bc\\u00bd\\u01c3\\u0337\\u0338"
+ "\\u05c3\\u05f4\\u06d4\\u0702\\u115f\\u1160][\\u2000-\\u200b]"
+ "[\\u2024\\u2027\\u2028\\u2029\\u2039\\u203a\\u2044\\u205f]"
+ "[\\u2154-\\u2156][\\u2159-\\u215b][\\u215f\\u2215\\u23ae"
+ "\\u29f6\\u29f8\\u2afb\\u2afd][\\u2ff0-\\u2ffb][\\u3014"
+ "\\u3015\\u3033\\u3164\\u321d\\u321e\\u33ae\\u33af\\u33c6\\u33df\\ufe"
+ "14"
+ "\\ufe15\\ufe3f\\ufe5d\\ufe5e\\ufeff\\uff0e\\uff06\\uff61\\uffa0\\uff"
+ "f9]"
+ "[\\ufffa-\\ufffd]\\U0001f50f\\U0001f510\\U0001f512\\U0001f513]",
+ -1, US_INV),
+ status);
+ DCHECK(U_SUCCESS(status));
+ icu::RegexMatcher dangerous_patterns(
+ icu::UnicodeString(
+ // Lone katakana no, so, or n
+ "[^\\p{Katakana}][\\u30ce\\u30f3\\u30bd][^\\p{Katakana}]"
+ // Repeating Japanese accent characters
+ "|[\\u3099\\u309a\\u309b\\u309c][\\u3099\\u309a\\u309b\\u309c]"),
+ 0, status);
+#endif
+ DCHECK(U_SUCCESS(status));
+ icu::UnicodeSet component_characters;
+ icu::UnicodeString component_string(str, str_len);
+ component_characters.addAll(component_string);
+ if (dangerous_characters.containsSome(component_characters))
+ return false;
+
+ DCHECK(U_SUCCESS(status));
+ dangerous_patterns.reset(component_string);
+ if (dangerous_patterns.find())
+ return false;
+
+ // If the language list is empty, the result is completely determined
+ // by whether a component is a single script or not. This will block
+ // even "safe" script mixing cases like <Chinese, Latin-ASCII> that are
+ // allowed with |languages| (while it blocks Chinese + Latin letters with
+ // an accent as should be the case), but we want to err on the safe side
+ // when |languages| is empty.
+ if (languages.empty())
+ return IsIDNComponentInSingleScript(str, str_len);
+
+ // |common_characters| is made up of ASCII numbers, hyphen, plus and
+ // underscore that are used across scripts and allowed in domain names.
+ // (sync'd with characters allowed in url_canon_host with square
+ // brackets excluded.) See kHostCharLookup[] array in url_canon_host.cc.
+ icu::UnicodeSet common_characters(UNICODE_STRING_SIMPLE("[[0-9]\\-_+\\ ]"),
+ status);
+ DCHECK(U_SUCCESS(status));
+ // Subtract common characters because they're always allowed so that
+ // we just have to check if a language-specific set contains
+ // the remainder.
+ component_characters.removeAll(common_characters);
+
+ base::StringTokenizer t(languages, ",");
+ while (t.GetNext()) {
+ if (IsComponentCoveredByLang(component_characters, t.token()))
+ return true;
+ }
+ return false;
+}
+
+// A wrapper to use LazyInstance<>::Leaky with ICU's UIDNA, a C pointer to
+// a UTS46/IDNA 2008 handling object opened with uidna_openUTS46().
+//
+// We use UTS46 with BiDiCheck to migrate from IDNA 2003 to IDNA 2008 with
+// the backward compatibility in mind. What it does:
+//
+// 1. Use the up-to-date Unicode data.
+// 2. Define a case folding/mapping with the up-to-date Unicode data as
+// in IDNA 2003.
+// 3. Use transitional mechanism for 4 deviation characters (sharp-s,
+// final sigma, ZWJ and ZWNJ) for now.
+// 4. Continue to allow symbols and punctuations.
+// 5. Apply new BiDi check rules more permissive than the IDNA 2003 BiDI rules.
+// 6. Do not apply STD3 rules
+// 7. Do not allow unassigned code points.
+//
+// It also closely matches what IE 10 does except for the BiDi check (
+// http://goo.gl/3XBhqw ).
+// See http://http://unicode.org/reports/tr46/ and references therein
+// for more details.
+struct UIDNAWrapper {
+ UIDNAWrapper() {
+ UErrorCode err = U_ZERO_ERROR;
+ // TODO(jungshik): Change options as different parties (browsers,
+ // registrars, search engines) converge toward a consensus.
+ value = uidna_openUTS46(UIDNA_CHECK_BIDI, &err);
+ if (U_FAILURE(err))
+ value = NULL;
+ }
+
+ UIDNA* value;
+};
+
+static base::LazyInstance<UIDNAWrapper>::Leaky g_uidna =
+ LAZY_INSTANCE_INITIALIZER;
+
+// Converts one component of a host (between dots) to IDN if safe. The result
+// will be APPENDED to the given output string and will be the same as the input
+// if it is not IDN or the IDN is unsafe to display. Returns whether any
+// conversion was performed.
+bool IDNToUnicodeOneComponent(const base::char16* comp,
+ size_t comp_len,
+ const std::string& languages,
+ base::string16* out) {
+ DCHECK(out);
+ if (comp_len == 0)
+ return false;
+
+ // Only transform if the input can be an IDN component.
+ static const base::char16 kIdnPrefix[] = {'x', 'n', '-', '-'};
+ if ((comp_len > arraysize(kIdnPrefix)) &&
+ !memcmp(comp, kIdnPrefix, sizeof(kIdnPrefix))) {
+ UIDNA* uidna = g_uidna.Get().value;
+ DCHECK(uidna != NULL);
+ size_t original_length = out->length();
+ int output_length = 64;
+ UIDNAInfo info = UIDNA_INFO_INITIALIZER;
+ UErrorCode status;
+ do {
+ out->resize(original_length + output_length);
+ status = U_ZERO_ERROR;
+ // This returns the actual length required. If this is more than 64
+ // code units, |status| will be U_BUFFER_OVERFLOW_ERROR and we'll try
+ // the conversion again, but with a sufficiently large buffer.
+ output_length = uidna_labelToUnicode(
+ uidna, comp, static_cast<int32_t>(comp_len), &(*out)[original_length],
+ output_length, &info, &status);
+ } while ((status == U_BUFFER_OVERFLOW_ERROR && info.errors == 0));
+
+ if (U_SUCCESS(status) && info.errors == 0) {
+ // Converted successfully. Ensure that the converted component
+ // can be safely displayed to the user.
+ out->resize(original_length + output_length);
+ if (IsIDNComponentSafe(out->data() + original_length, output_length,
+ languages))
+ return true;
+ }
+
+ // Something went wrong. Revert to original string.
+ out->resize(original_length);
+ }
+
+ // We get here with no IDN or on error, in which case we just append the
+ // literal input.
+ out->append(comp, comp_len);
+ return false;
+}
+
+} // namespace
+
+const FormatUrlType kFormatUrlOmitNothing = 0;
+const FormatUrlType kFormatUrlOmitUsernamePassword = 1 << 0;
+const FormatUrlType kFormatUrlOmitHTTP = 1 << 1;
+const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname = 1 << 2;
+const FormatUrlType kFormatUrlOmitAll =
+ kFormatUrlOmitUsernamePassword | kFormatUrlOmitHTTP |
+ kFormatUrlOmitTrailingSlashOnBareHostname;
+
+base::string16 FormatUrl(const GURL& url,
+ const std::string& languages,
+ FormatUrlTypes format_types,
+ net::UnescapeRule::Type unescape_rules,
+ url::Parsed* new_parsed,
+ size_t* prefix_end,
+ size_t* offset_for_adjustment) {
+ std::vector<size_t> offsets;
+ if (offset_for_adjustment)
+ offsets.push_back(*offset_for_adjustment);
+ base::string16 result =
+ FormatUrlWithOffsets(url, languages, format_types, unescape_rules,
+ new_parsed, prefix_end, &offsets);
+ if (offset_for_adjustment)
+ *offset_for_adjustment = offsets[0];
+ return result;
+}
+
+base::string16 FormatUrlWithOffsets(
+ const GURL& url,
+ const std::string& languages,
+ FormatUrlTypes format_types,
+ net::UnescapeRule::Type unescape_rules,
+ url::Parsed* new_parsed,
+ size_t* prefix_end,
+ std::vector<size_t>* offsets_for_adjustment) {
+ base::OffsetAdjuster::Adjustments adjustments;
+ const base::string16& format_url_return_value =
+ FormatUrlWithAdjustments(url, languages, format_types, unescape_rules,
+ new_parsed, prefix_end, &adjustments);
+ base::OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment);
+ if (offsets_for_adjustment) {
+ std::for_each(
+ offsets_for_adjustment->begin(), offsets_for_adjustment->end(),
+ base::LimitOffset<std::string>(format_url_return_value.length()));
+ }
+ return format_url_return_value;
+}
+
+base::string16 FormatUrlWithAdjustments(
+ const GURL& url,
+ const std::string& languages,
+ FormatUrlTypes format_types,
+ net::UnescapeRule::Type unescape_rules,
+ url::Parsed* new_parsed,
+ size_t* prefix_end,
+ base::OffsetAdjuster::Adjustments* adjustments) {
+ DCHECK(adjustments != NULL);
+ adjustments->clear();
+ url::Parsed parsed_temp;
+ if (!new_parsed)
+ new_parsed = &parsed_temp;
+ else
+ *new_parsed = url::Parsed();
+
+ // Special handling for view-source:. Don't use content::kViewSourceScheme
+ // because this library shouldn't depend on chrome.
+ const char kViewSource[] = "view-source";
+ // Reject "view-source:view-source:..." to avoid deep recursion.
+ const char kViewSourceTwice[] = "view-source:view-source:";
+ if (url.SchemeIs(kViewSource) &&
+ !base::StartsWith(url.possibly_invalid_spec(), kViewSourceTwice,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return FormatViewSourceUrl(url, languages, format_types, unescape_rules,
+ new_parsed, prefix_end, adjustments);
+ }
+
+ // We handle both valid and invalid URLs (this will give us the spec
+ // regardless of validity).
+ const std::string& spec = url.possibly_invalid_spec();
+ const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec();
+
+ // Scheme & separators. These are ASCII.
+ base::string16 url_string;
+ url_string.insert(
+ url_string.end(), spec.begin(),
+ spec.begin() + parsed.CountCharactersBefore(url::Parsed::USERNAME, true));
+ const char kHTTP[] = "http://";
+ const char kFTP[] = "ftp.";
+ // url_formatter::FixupURL() treats "ftp.foo.com" as ftp://ftp.foo.com. This
+ // means that if we trim "http://" off a URL whose host starts with "ftp." and
+ // the user inputs this into any field subject to fixup (which is basically
+ // all input fields), the meaning would be changed. (In fact, often the
+ // formatted URL is directly pre-filled into an input field.) For this reason
+ // we avoid stripping "http://" in this case.
+ bool omit_http =
+ (format_types & kFormatUrlOmitHTTP) &&
+ base::EqualsASCII(url_string, kHTTP) &&
+ !base::StartsWith(url.host(), kFTP, base::CompareCase::SENSITIVE);
+ new_parsed->scheme = parsed.scheme;
+
+ // Username & password.
+ if ((format_types & kFormatUrlOmitUsernamePassword) != 0) {
+ // Remove the username and password fields. We don't want to display those
+ // to the user since they can be used for attacks,
+ // e.g. "http://google.com:search@evil.ru/"
+ new_parsed->username.reset();
+ new_parsed->password.reset();
+ // Update the adjustments based on removed username and/or password.
+ if (parsed.username.is_nonempty() || parsed.password.is_nonempty()) {
+ if (parsed.username.is_nonempty() && parsed.password.is_nonempty()) {
+ // The seeming off-by-two is to account for the ':' after the username
+ // and '@' after the password.
+ adjustments->push_back(base::OffsetAdjuster::Adjustment(
+ static_cast<size_t>(parsed.username.begin),
+ static_cast<size_t>(parsed.username.len + parsed.password.len + 2),
+ 0));
+ } else {
+ const url::Component* nonempty_component =
+ parsed.username.is_nonempty() ? &parsed.username : &parsed.password;
+ // The seeming off-by-one is to account for the '@' after the
+ // username/password.
+ adjustments->push_back(base::OffsetAdjuster::Adjustment(
+ static_cast<size_t>(nonempty_component->begin),
+ static_cast<size_t>(nonempty_component->len + 1), 0));
+ }
+ }
+ } else {
+ AppendFormattedComponent(spec, parsed.username,
+ NonHostComponentTransform(unescape_rules),
+ &url_string, &new_parsed->username, adjustments);
+ if (parsed.password.is_valid())
+ url_string.push_back(':');
+ AppendFormattedComponent(spec, parsed.password,
+ NonHostComponentTransform(unescape_rules),
+ &url_string, &new_parsed->password, adjustments);
+ if (parsed.username.is_valid() || parsed.password.is_valid())
+ url_string.push_back('@');
+ }
+ if (prefix_end)
+ *prefix_end = static_cast<size_t>(url_string.length());
+
+ // Host.
+ AppendFormattedComponent(spec, parsed.host, HostComponentTransform(languages),
+ &url_string, &new_parsed->host, adjustments);
+
+ // Port.
+ if (parsed.port.is_nonempty()) {
+ url_string.push_back(':');
+ new_parsed->port.begin = url_string.length();
+ url_string.insert(url_string.end(), spec.begin() + parsed.port.begin,
+ spec.begin() + parsed.port.end());
+ new_parsed->port.len = url_string.length() - new_parsed->port.begin;
+ } else {
+ new_parsed->port.reset();
+ }
+
+ // Path & query. Both get the same general unescape & convert treatment.
+ if (!(format_types & kFormatUrlOmitTrailingSlashOnBareHostname) ||
+ !CanStripTrailingSlash(url)) {
+ AppendFormattedComponent(spec, parsed.path,
+ NonHostComponentTransform(unescape_rules),
+ &url_string, &new_parsed->path, adjustments);
+ } else {
+ if (parsed.path.len > 0) {
+ adjustments->push_back(base::OffsetAdjuster::Adjustment(
+ parsed.path.begin, parsed.path.len, 0));
+ }
+ }
+ if (parsed.query.is_valid())
+ url_string.push_back('?');
+ AppendFormattedComponent(spec, parsed.query,
+ NonHostComponentTransform(unescape_rules),
+ &url_string, &new_parsed->query, adjustments);
+
+ // Ref. This is valid, unescaped UTF-8, so we can just convert.
+ if (parsed.ref.is_valid())
+ url_string.push_back('#');
+ AppendFormattedComponent(spec, parsed.ref,
+ NonHostComponentTransform(net::UnescapeRule::NONE),
+ &url_string, &new_parsed->ref, adjustments);
+
+ // If we need to strip out http do it after the fact.
+ if (omit_http && base::StartsWith(url_string, base::ASCIIToUTF16(kHTTP),
+ base::CompareCase::SENSITIVE)) {
+ const size_t kHTTPSize = arraysize(kHTTP) - 1;
+ url_string = url_string.substr(kHTTPSize);
+ // Because offsets in the |adjustments| are already calculated with respect
+ // to the string with the http:// prefix in it, those offsets remain correct
+ // after stripping the prefix. The only thing necessary is to add an
+ // adjustment to reflect the stripped prefix.
+ adjustments->insert(adjustments->begin(),
+ base::OffsetAdjuster::Adjustment(0, kHTTPSize, 0));
+
+ if (prefix_end)
+ *prefix_end -= kHTTPSize;
+
+ // Adjust new_parsed.
+ DCHECK(new_parsed->scheme.is_valid());
+ int delta = -(new_parsed->scheme.len + 3); // +3 for ://.
+ new_parsed->scheme.reset();
+ AdjustAllComponentsButScheme(delta, new_parsed);
+ }
+
+ return url_string;
+}
+
+bool CanStripTrailingSlash(const GURL& url) {
+ // Omit the path only for standard, non-file URLs with nothing but "/" after
+ // the hostname.
+ return url.IsStandard() && !url.SchemeIsFile() && !url.SchemeIsFileSystem() &&
+ !url.has_query() && !url.has_ref() && url.path() == "/";
+}
+
+void AppendFormattedHost(const GURL& url,
+ const std::string& languages,
+ base::string16* output) {
+ AppendFormattedComponent(
+ url.possibly_invalid_spec(), url.parsed_for_possibly_invalid_spec().host,
+ HostComponentTransform(languages), output, NULL, NULL);
+}
+
+base::string16 IDNToUnicode(const std::string& host,
+ const std::string& languages) {
+ return IDNToUnicodeWithAdjustments(host, languages, NULL);
+}
+
+} // url_formatter
diff --git a/chromium/components/url_formatter/url_formatter.gyp b/chromium/components/url_formatter/url_formatter.gyp
new file mode 100644
index 00000000000..9375e96d93d
--- /dev/null
+++ b/chromium/components/url_formatter/url_formatter.gyp
@@ -0,0 +1,39 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ # GN version: //components/url_formatter
+ 'target_name': 'url_formatter',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../../base/base.gyp:base',
+ '../../net/net.gyp:net',
+ '../../third_party/icu/icu.gyp:icui18n',
+ '../../third_party/icu/icu.gyp:icuuc',
+ '../../url/url.gyp:url_lib',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'elide_url.cc',
+ 'elide_url.h',
+ 'url_fixer.cc',
+ 'url_fixer.h',
+ 'url_formatter.cc',
+ 'url_formatter.h',
+ ],
+ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+ 'msvs_disabled_warnings': [4267, ],
+
+ 'conditions': [
+ ['OS != "android"', {
+ 'dependencies': [
+ '../../ui/gfx/gfx.gyp:gfx',
+ ]
+ }],
+ ],
+ },
+ ],
+}
diff --git a/chromium/components/url_formatter/url_formatter.h b/chromium/components/url_formatter/url_formatter.h
new file mode 100644
index 00000000000..01c8795ce06
--- /dev/null
+++ b/chromium/components/url_formatter/url_formatter.h
@@ -0,0 +1,155 @@
+// 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.
+
+// url_formatter contains routines for formatting URLs in a way that can be
+// safely and securely displayed to users. For example, it is responsible
+// for determining when to convert an IDN A-Label (e.g. "xn--[something]")
+// into the IDN U-Label.
+//
+// Note that this formatting is only intended for display purposes; it would
+// be insecure and insufficient to make comparisons solely on formatted URLs
+// (that is, it should not be used for normalizing URLs for comparison for
+// security decisions).
+
+#ifndef COMPONENTS_URL_FORMATTER_URL_FORMATTER_H_
+#define COMPONENTS_URL_FORMATTER_URL_FORMATTER_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "base/strings/utf_offset_string_conversions.h"
+#include "net/base/escape.h"
+
+class GURL;
+
+namespace url {
+struct Parsed;
+} // url
+
+namespace url_formatter {
+
+// Used by FormatUrl to specify handling of certain parts of the url.
+typedef uint32_t FormatUrlType;
+typedef uint32_t FormatUrlTypes;
+
+// Nothing is ommitted.
+extern const FormatUrlType kFormatUrlOmitNothing;
+
+// If set, any username and password are removed.
+extern const FormatUrlType kFormatUrlOmitUsernamePassword;
+
+// If the scheme is 'http://', it's removed.
+extern const FormatUrlType kFormatUrlOmitHTTP;
+
+// Omits the path if it is just a slash and there is no query or ref. This is
+// meaningful for non-file "standard" URLs.
+extern const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname;
+
+// Convenience for omitting all unecessary types.
+extern const FormatUrlType kFormatUrlOmitAll;
+
+// Creates a string representation of |url|. The IDN host name may be in Unicode
+// if |languages| accepts the Unicode representation. |format_type| is a bitmask
+// of FormatUrlTypes, see it for details. |unescape_rules| defines how to clean
+// the URL for human readability. You will generally want |UnescapeRule::SPACES|
+// for display to the user if you can handle spaces, or |UnescapeRule::NORMAL|
+// if not. If the path part and the query part seem to be encoded in %-encoded
+// UTF-8, decodes %-encoding and UTF-8.
+//
+// The last three parameters may be NULL.
+//
+// |new_parsed| will be set to the parsing parameters of the resultant URL.
+//
+// |prefix_end| will be the length before the hostname of the resultant URL.
+//
+// |offset[s]_for_adjustment| specifies one or more offsets into the original
+// URL, representing insertion or selection points between characters: if the
+// input is "http://foo.com/", offset 0 is before the entire URL, offset 7 is
+// between the scheme and the host, and offset 15 is after the end of the URL.
+// Valid input offsets range from 0 to the length of the input URL string. On
+// exit, each offset will have been modified to reflect any changes made to the
+// output string. For example, if |url| is "http://a:b@c.com/",
+// |omit_username_password| is true, and an offset is 12 (pointing between 'c'
+// and '.'), then on return the output string will be "http://c.com/" and the
+// offset will be 8. If an offset cannot be successfully adjusted (e.g. because
+// it points into the middle of a component that was entirely removed or into
+// the middle of an encoding sequence), it will be set to base::string16::npos.
+// For consistency, if an input offset points between the scheme and the
+// username/password, and both are removed, on output this offset will be 0
+// rather than npos; this means that offsets at the starts and ends of removed
+// components are always transformed the same way regardless of what other
+// components are adjacent.
+base::string16 FormatUrl(const GURL& url,
+ const std::string& languages,
+ FormatUrlTypes format_types,
+ net::UnescapeRule::Type unescape_rules,
+ url::Parsed* new_parsed,
+ size_t* prefix_end,
+ size_t* offset_for_adjustment);
+
+base::string16 FormatUrlWithOffsets(
+ const GURL& url,
+ const std::string& languages,
+ FormatUrlTypes format_types,
+ net::UnescapeRule::Type unescape_rules,
+ url::Parsed* new_parsed,
+ size_t* prefix_end,
+ std::vector<size_t>* offsets_for_adjustment);
+
+// This function is like those above except it takes |adjustments| rather
+// than |offset[s]_for_adjustment|. |adjustments| will be set to reflect all
+// the transformations that happened to |url| to convert it into the returned
+// value.
+base::string16 FormatUrlWithAdjustments(
+ const GURL& url,
+ const std::string& languages,
+ FormatUrlTypes format_types,
+ net::UnescapeRule::Type unescape_rules,
+ url::Parsed* new_parsed,
+ size_t* prefix_end,
+ base::OffsetAdjuster::Adjustments* adjustments);
+
+// This is a convenience function for FormatUrl() with
+// format_types = kFormatUrlOmitAll and unescape = SPACES. This is the typical
+// set of flags for "URLs to display to the user". You should be cautious about
+// using this for URLs which will be parsed or sent to other applications.
+inline base::string16 FormatUrl(const GURL& url, const std::string& languages) {
+ return FormatUrl(url, languages, kFormatUrlOmitAll, net::UnescapeRule::SPACES,
+ nullptr, nullptr, nullptr);
+}
+
+// Returns whether FormatUrl() would strip a trailing slash from |url|, given a
+// format flag including kFormatUrlOmitTrailingSlashOnBareHostname.
+bool CanStripTrailingSlash(const GURL& url);
+
+// Formats the host in |url| and appends it to |output|. The host formatter
+// takes the same accept languages component as ElideURL().
+void AppendFormattedHost(const GURL& url,
+ const std::string& languages,
+ base::string16* output);
+
+// Converts the given host name to unicode characters. This can be called for
+// any host name, if the input is not IDN or is invalid in some way, we'll just
+// return the ASCII source so it is still usable.
+//
+// The input should be the canonicalized ASCII host name from GURL. This
+// function does NOT accept UTF-8!
+//
+// |languages| is a comma separated list of ISO 639 language codes. It
+// is used to determine whether a hostname is 'comprehensible' to a user
+// who understands languages listed. |host| will be converted to a
+// human-readable form (Unicode) ONLY when each component of |host| is
+// regarded as 'comprehensible'. Scipt-mixing is not allowed except that
+// Latin letters in the ASCII range can be mixed with a limited set of
+// script-language pairs (currently Han, Kana and Hangul for zh,ja and ko).
+// When |languages| is empty, even that mixing is not allowed.
+base::string16 IDNToUnicode(const std::string& host,
+ const std::string& languages);
+
+} // url_formatter
+
+#endif // COMPONENTS_URL_FORMATTER_URL_FORMATTER_H_
diff --git a/chromium/components/url_formatter/url_formatter_unittest.cc b/chromium/components/url_formatter/url_formatter_unittest.cc
new file mode 100644
index 00000000000..0dd635a9488
--- /dev/null
+++ b/chromium/components/url_formatter/url_formatter_unittest.cc
@@ -0,0 +1,978 @@
+// 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/url_formatter/url_formatter.h"
+
+#include <string.h>
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+
+namespace url_formatter {
+
+namespace {
+
+using base::WideToUTF16;
+using base::ASCIIToUTF16;
+
+const size_t kNpos = base::string16::npos;
+
+const char* const kLanguages[] = {
+ "", "en", "zh-CN", "ja", "ko",
+ "he", "ar", "ru", "el", "fr",
+ "de", "pt", "sv", "th", "hi",
+ "de,en", "el,en", "zh-TW,en", "ko,ja", "he,ru,en",
+ "zh,ru,en"
+};
+
+struct IDNTestCase {
+ const char* const input;
+ const wchar_t* unicode_output;
+ const bool unicode_allowed[arraysize(kLanguages)];
+};
+
+// TODO(jungshik) This is just a random sample of languages and is far
+// from exhaustive. We may have to generate all the combinations
+// of languages (powerset of a set of all the languages).
+const IDNTestCase idn_cases[] = {
+ // No IDN
+ {"www.google.com", L"www.google.com",
+ {true, true, true, true, true,
+ true, true, true, true, true,
+ true, true, true, true, true,
+ true, true, true, true, true,
+ true}},
+ {"www.google.com.", L"www.google.com.",
+ {true, true, true, true, true,
+ true, true, true, true, true,
+ true, true, true, true, true,
+ true, true, true, true, true,
+ true}},
+ {".", L".",
+ {true, true, true, true, true,
+ true, true, true, true, true,
+ true, true, true, true, true,
+ true, true, true, true, true,
+ true}},
+ {"", L"",
+ {true, true, true, true, true,
+ true, true, true, true, true,
+ true, true, true, true, true,
+ true, true, true, true, true,
+ true}},
+ // IDN
+ // Hanzi (Traditional Chinese)
+ {"xn--1lq90ic7f1rc.cn", L"\x5317\x4eac\x5927\x5b78.cn",
+ {true, false, true, true, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, true, true, false,
+ true}},
+ // Hanzi ('video' in Simplified Chinese : will pass only in zh-CN,zh)
+ {"xn--cy2a840a.com", L"\x89c6\x9891.com",
+ {true, false, true, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ true}},
+ // Hanzi + '123'
+ {"www.xn--123-p18d.com", L"www.\x4e00" L"123.com",
+ {true, false, true, true, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, true, true, false,
+ true}},
+ // Hanzi + Latin : U+56FD is simplified and is regarded
+ // as not supported in zh-TW.
+ {"www.xn--hello-9n1hm04c.com", L"www.hello\x4e2d\x56fd.com",
+ {false, false, true, true, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, true, false,
+ true}},
+ // Kanji + Kana (Japanese)
+ {"xn--l8jvb1ey91xtjb.jp", L"\x671d\x65e5\x3042\x3055\x3072.jp",
+ {true, false, false, true, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, true, false,
+ false}},
+ // Katakana including U+30FC
+ {"xn--tckm4i2e.jp", L"\x30b3\x30de\x30fc\x30b9.jp",
+ {true, false, false, true, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, true, false,
+ }},
+ {"xn--3ck7a7g.jp", L"\u30ce\u30f3\u30bd.jp",
+ {true, false, false, true, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, true, false,
+ }},
+ // Katakana + Latin (Japanese)
+ // TODO(jungshik): Change 'false' in the first element to 'true'
+ // after upgrading to ICU 4.2.1 to use new uspoof_* APIs instead
+ // of our IsIDNComponentInSingleScript().
+ {"xn--e-efusa1mzf.jp", L"e\x30b3\x30de\x30fc\x30b9.jp",
+ {false, false, false, true, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, true, false,
+ }},
+ {"xn--3bkxe.jp", L"\x30c8\x309a.jp",
+ {false, false, false, true, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, true, false,
+ }},
+ // Hangul (Korean)
+ {"www.xn--or3b17p6jjc.kr", L"www.\xc804\xc790\xc815\xbd80.kr",
+ {true, false, false, false, true,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, true, false,
+ false}},
+ // b<u-umlaut>cher (German)
+ {"xn--bcher-kva.de", L"b\x00fc" L"cher.de",
+ {true, false, false, false, false,
+ false, false, false, false, true,
+ true, false, false, false, false,
+ true, false, false, false, false,
+ false}},
+ // a with diaeresis
+ {"www.xn--frgbolaget-q5a.se", L"www.f\x00e4rgbolaget.se",
+ {true, false, false, false, false,
+ false, false, false, false, false,
+ true, false, true, false, false,
+ true, false, false, false, false,
+ false}},
+ // c-cedilla (French)
+ {"www.xn--alliancefranaise-npb.fr", L"www.alliancefran\x00e7" L"aise.fr",
+ {true, false, false, false, false,
+ false, false, false, false, true,
+ false, true, false, false, false,
+ false, false, false, false, false,
+ false}},
+ // caf'e with acute accent' (French)
+ {"xn--caf-dma.fr", L"caf\x00e9.fr",
+ {true, false, false, false, false,
+ false, false, false, false, true,
+ false, true, true, false, false,
+ false, false, false, false, false,
+ false}},
+ // c-cedillla and a with tilde (Portuguese)
+ {"xn--poema-9qae5a.com.br", L"p\x00e3oema\x00e7\x00e3.com.br",
+ {true, false, false, false, false,
+ false, false, false, false, false,
+ false, true, false, false, false,
+ false, false, false, false, false,
+ false}},
+ // s with caron
+ {"xn--achy-f6a.com", L"\x0161" L"achy.com",
+ {true, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false}},
+ // TODO(jungshik) : Add examples with Cyrillic letters
+ // only used in some languages written in Cyrillic.
+ // Eutopia (Greek)
+ {"xn--kxae4bafwg.gr", L"\x03bf\x03c5\x03c4\x03bf\x03c0\x03af\x03b1.gr",
+ {true, false, false, false, false,
+ false, false, false, true, false,
+ false, false, false, false, false,
+ false, true, false, false, false,
+ false}},
+ // Eutopia + 123 (Greek)
+ {"xn---123-pldm0haj2bk.gr",
+ L"\x03bf\x03c5\x03c4\x03bf\x03c0\x03af\x03b1-123.gr",
+ {true, false, false, false, false,
+ false, false, false, true, false,
+ false, false, false, false, false,
+ false, true, false, false, false,
+ false}},
+ // Cyrillic (Russian)
+ {"xn--n1aeec9b.ru", L"\x0442\x043e\x0440\x0442\x044b.ru",
+ {true, false, false, false, false,
+ false, false, true, false, false,
+ false, false, false, false, false,
+ false, false, false, false, true,
+ true}},
+ // Cyrillic + 123 (Russian)
+ {"xn---123-45dmmc5f.ru", L"\x0442\x043e\x0440\x0442\x044b-123.ru",
+ {true, false, false, false, false,
+ false, false, true, false, false,
+ false, false, false, false, false,
+ false, false, false, false, true,
+ true}},
+ // Arabic
+ {"xn--mgba1fmg.ar", L"\x0627\x0641\x0644\x0627\x0645.ar",
+ {true, false, false, false, false,
+ false, true, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false}},
+ // Hebrew
+ {"xn--4dbib.he", L"\x05d5\x05d0\x05d4.he",
+ {true, false, false, false, false,
+ true, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, true,
+ false}},
+ // Thai
+ {"xn--12c2cc4ag3b4ccu.th",
+ L"\x0e2a\x0e32\x0e22\x0e01\x0e32\x0e23\x0e1a\x0e34\x0e19.th",
+ {true, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, true, false,
+ false, false, false, false, false,
+ false}},
+ // Devangari (Hindi)
+ {"www.xn--l1b6a9e1b7c.in", L"www.\x0905\x0915\x094b\x0932\x093e.in",
+ {true, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, true,
+ false, false, false, false, false,
+ false}},
+ // Invalid IDN
+ {"xn--hello?world.com", NULL,
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false}},
+ // Unsafe IDNs
+ // "payp<alpha>l.com"
+ {"www.xn--paypl-g9d.com", L"payp\x03b1l.com",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false}},
+ // google.gr with Greek omicron and epsilon
+ {"xn--ggl-6xc1ca.gr", L"g\x03bf\x03bfgl\x03b5.gr",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false}},
+ // google.ru with Cyrillic o
+ {"xn--ggl-tdd6ba.ru", L"g\x043e\x043egl\x0435.ru",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false}},
+ // h<e with acute>llo<China in Han>.cn
+ {"xn--hllo-bpa7979ih5m.cn", L"h\x00e9llo\x4e2d\x56fd.cn",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false}},
+ // <Greek rho><Cyrillic a><Cyrillic u>.ru
+ {"xn--2xa6t2b.ru", L"\x03c1\x0430\x0443.ru",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false}},
+ // One that's really long that will force a buffer realloc
+ {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaa",
+ L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ L"aaaaaaaa",
+ {true, true, true, true, true,
+ true, true, true, true, true,
+ true, true, true, true, true,
+ true, true, true, true, true,
+ true}},
+ // Test cases for characters we blacklisted although allowed in IDN.
+ // Embedded spaces will be turned to %20 in the display.
+ // TODO(jungshik): We need to have more cases. This is a typical
+ // data-driven trap. The following test cases need to be separated
+ // and tested only for a couple of languages.
+ {"xn--osd3820f24c.kr", L"\xac00\xb098\x115f.kr",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false}},
+ {"www.xn--google-ho0coa.com", L"www.\x2039google\x203a.com",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ }},
+ {"google.xn--comabc-k8d", L"google.com\x0338" L"abc",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ }},
+ {"google.xn--com-oh4ba.evil.jp", L"google.com\x309a\x309a.evil.jp",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ }},
+ {"google.xn--comevil-v04f.jp", L"google.com\x30ce" L"evil.jp",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ }},
+ // Padlock icon spoof.
+ {"xn--google-hj64e", L"\U0001f512google.com",
+ {false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ }},
+ // Ensure that blacklisting "\xd83d\xdd12" did not inadvertently blacklist
+ // all strings with the surrogate '\xdd12'.
+ {"xn--fk9c.com", L"\U00010912.com",
+ {true, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ }},
+#if 0
+ // These two cases are special. We need a separate test.
+ // U+3000 and U+3002 are normalized to ASCII space and dot.
+ {"xn-- -kq6ay5z.cn", L"\x4e2d\x56fd\x3000.cn",
+ {false, false, true, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, true, false, false,
+ true}},
+ {"xn--fiqs8s.cn", L"\x4e2d\x56fd\x3002" L"cn",
+ {false, false, true, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, true, false, false,
+ true}},
+#endif
+};
+
+struct AdjustOffsetCase {
+ size_t input_offset;
+ size_t output_offset;
+};
+
+struct UrlTestData {
+ const char* const description;
+ const char* const input;
+ const char* const languages;
+ FormatUrlTypes format_types;
+ net::UnescapeRule::Type escape_rules;
+ const wchar_t* output; // Use |wchar_t| to handle Unicode constants easily.
+ size_t prefix_len;
+};
+
+// A helper for IDN*{Fast,Slow}.
+// Append "::<language list>" to |expected| and |actual| to make it
+// easy to tell which sub-case fails without debugging.
+void AppendLanguagesToOutputs(const char* languages,
+ base::string16* expected,
+ base::string16* actual) {
+ base::string16 to_append = ASCIIToUTF16("::") + ASCIIToUTF16(languages);
+ expected->append(to_append);
+ actual->append(to_append);
+}
+
+// A pair of helpers for the FormatUrlWithOffsets() test.
+void VerboseExpect(size_t expected,
+ size_t actual,
+ const std::string& original_url,
+ size_t position,
+ const base::string16& formatted_url) {
+ EXPECT_EQ(expected, actual) << "Original URL: " << original_url
+ << " (at char " << position << ")\nFormatted URL: " << formatted_url;
+}
+
+void CheckAdjustedOffsets(const std::string& url_string,
+ const std::string& languages,
+ FormatUrlTypes format_types,
+ net::UnescapeRule::Type unescape_rules,
+ const size_t* output_offsets) {
+ GURL url(url_string);
+ size_t url_length = url_string.length();
+ std::vector<size_t> offsets;
+ for (size_t i = 0; i <= url_length + 1; ++i)
+ offsets.push_back(i);
+ offsets.push_back(500000); // Something larger than any input length.
+ offsets.push_back(std::string::npos);
+ base::string16 formatted_url = FormatUrlWithOffsets(url, languages,
+ format_types, unescape_rules, NULL, NULL, &offsets);
+ for (size_t i = 0; i < url_length; ++i)
+ VerboseExpect(output_offsets[i], offsets[i], url_string, i, formatted_url);
+ VerboseExpect(formatted_url.length(), offsets[url_length], url_string,
+ url_length, formatted_url);
+ VerboseExpect(base::string16::npos, offsets[url_length + 1], url_string,
+ 500000, formatted_url);
+ VerboseExpect(base::string16::npos, offsets[url_length + 2], url_string,
+ std::string::npos, formatted_url);
+}
+
+TEST(UrlFormatterTest, IDNToUnicodeFast) {
+ for (size_t i = 0; i < arraysize(idn_cases); i++) {
+ for (size_t j = 0; j < arraysize(kLanguages); j++) {
+ // ja || zh-TW,en || ko,ja -> IDNToUnicodeSlow
+ if (j == 3 || j == 17 || j == 18)
+ continue;
+ base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j]));
+ base::string16 expected(idn_cases[i].unicode_allowed[j] ?
+ WideToUTF16(idn_cases[i].unicode_output) :
+ ASCIIToUTF16(idn_cases[i].input));
+ AppendLanguagesToOutputs(kLanguages[j], &expected, &output);
+ EXPECT_EQ(expected, output) << "input: \"" << idn_cases[i].input
+ << "\", languages: \"" << kLanguages[j]
+ << "\"";
+ }
+ }
+}
+
+TEST(UrlFormatterTest, IDNToUnicodeSlow) {
+ for (size_t i = 0; i < arraysize(idn_cases); i++) {
+ for (size_t j = 0; j < arraysize(kLanguages); j++) {
+ // !(ja || zh-TW,en || ko,ja) -> IDNToUnicodeFast
+ if (!(j == 3 || j == 17 || j == 18))
+ continue;
+ base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j]));
+ base::string16 expected(idn_cases[i].unicode_allowed[j] ?
+ WideToUTF16(idn_cases[i].unicode_output) :
+ ASCIIToUTF16(idn_cases[i].input));
+ AppendLanguagesToOutputs(kLanguages[j], &expected, &output);
+ EXPECT_EQ(expected, output) << "input: \"" << idn_cases[i].input
+ << "\", languages: \"" << kLanguages[j]
+ << "\"";
+ }
+ }
+}
+
+// ulocdata_getExemplarSet may fail with some locales (currently bn, gu, and
+// te), which was causing a crash (See http://crbug.com/510551). This may be an
+// icu bug, but regardless, that should not cause a crash.
+TEST(UrlFormatterTest, IDNToUnicodeNeverCrashes) {
+ for (char c1 = 'a'; c1 <= 'z'; c1++) {
+ for (char c2 = 'a'; c2 <= 'z'; c2++) {
+ std::string lang = base::StringPrintf("%c%c", c1, c2);
+ base::string16 output(IDNToUnicode("xn--74h", lang));
+ }
+ }
+}
+
+TEST(UrlFormatterTest, FormatUrl) {
+ FormatUrlTypes default_format_type = kFormatUrlOmitUsernamePassword;
+ const UrlTestData tests[] = {
+ {"Empty URL", "", "", default_format_type, net::UnescapeRule::NORMAL, L"",
+ 0},
+
+ {"Simple URL", "http://www.google.com/", "", default_format_type,
+ net::UnescapeRule::NORMAL, L"http://www.google.com/", 7},
+
+ {"With a port number and a reference",
+ "http://www.google.com:8080/#\xE3\x82\xB0", "", default_format_type,
+ net::UnescapeRule::NORMAL, L"http://www.google.com:8080/#\x30B0", 7},
+
+ // -------- IDN tests --------
+ {"Japanese IDN with ja", "http://xn--l8jvb1ey91xtjb.jp", "ja",
+ default_format_type, net::UnescapeRule::NORMAL,
+ L"http://\x671d\x65e5\x3042\x3055\x3072.jp/", 7},
+
+ {"Japanese IDN with en", "http://xn--l8jvb1ey91xtjb.jp", "en",
+ default_format_type, net::UnescapeRule::NORMAL,
+ L"http://xn--l8jvb1ey91xtjb.jp/", 7},
+
+ {"Japanese IDN without any languages", "http://xn--l8jvb1ey91xtjb.jp", "",
+ default_format_type, net::UnescapeRule::NORMAL,
+ // Single script is safe for empty languages.
+ L"http://\x671d\x65e5\x3042\x3055\x3072.jp/", 7},
+
+ {"mailto: with Japanese IDN", "mailto:foo@xn--l8jvb1ey91xtjb.jp", "ja",
+ default_format_type, net::UnescapeRule::NORMAL,
+ // GURL doesn't assume an email address's domain part as a host name.
+ L"mailto:foo@xn--l8jvb1ey91xtjb.jp", 7},
+
+ {"file: with Japanese IDN", "file://xn--l8jvb1ey91xtjb.jp/config.sys",
+ "ja", default_format_type, net::UnescapeRule::NORMAL,
+ L"file://\x671d\x65e5\x3042\x3055\x3072.jp/config.sys", 7},
+
+ {"ftp: with Japanese IDN", "ftp://xn--l8jvb1ey91xtjb.jp/config.sys", "ja",
+ default_format_type, net::UnescapeRule::NORMAL,
+ L"ftp://\x671d\x65e5\x3042\x3055\x3072.jp/config.sys", 6},
+
+ // -------- omit_username_password flag tests --------
+ {"With username and password, omit_username_password=false",
+ "http://user:passwd@example.com/foo", "", kFormatUrlOmitNothing,
+ net::UnescapeRule::NORMAL, L"http://user:passwd@example.com/foo", 19},
+
+ {"With username and password, omit_username_password=true",
+ "http://user:passwd@example.com/foo", "", default_format_type,
+ net::UnescapeRule::NORMAL, L"http://example.com/foo", 7},
+
+ {"With username and no password", "http://user@example.com/foo", "",
+ default_format_type, net::UnescapeRule::NORMAL,
+ L"http://example.com/foo", 7},
+
+ {"Just '@' without username and password", "http://@example.com/foo", "",
+ default_format_type, net::UnescapeRule::NORMAL,
+ L"http://example.com/foo", 7},
+
+ // GURL doesn't think local-part of an email address is username for URL.
+ {"mailto:, omit_username_password=true", "mailto:foo@example.com", "",
+ default_format_type, net::UnescapeRule::NORMAL,
+ L"mailto:foo@example.com", 7},
+
+ // -------- unescape flag tests --------
+ {"Do not unescape",
+ "http://%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB.jp/"
+ "%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB"
+ "?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB",
+ "en", default_format_type, net::UnescapeRule::NONE,
+ // GURL parses %-encoded hostnames into Punycode.
+ L"http://xn--qcka1pmc.jp/%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB"
+ L"?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB",
+ 7},
+
+ {"Unescape normally",
+ "http://%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB.jp/"
+ "%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB"
+ "?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB",
+ "en", default_format_type, net::UnescapeRule::NORMAL,
+ L"http://xn--qcka1pmc.jp/\x30B0\x30FC\x30B0\x30EB"
+ L"?q=\x30B0\x30FC\x30B0\x30EB",
+ 7},
+
+ {"Unescape normally with BiDi control character",
+ "http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", "en",
+ default_format_type, net::UnescapeRule::NORMAL,
+ L"http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", 7},
+
+ {"Unescape normally including unescape spaces",
+ "http://www.google.com/search?q=Hello%20World", "en",
+ default_format_type, net::UnescapeRule::SPACES,
+ L"http://www.google.com/search?q=Hello World", 7},
+
+ /*
+ {"unescape=true with some special characters",
+ "http://user%3A:%40passwd@example.com/foo%3Fbar?q=b%26z", "",
+ kFormatUrlOmitNothing, net::UnescapeRule::NORMAL,
+ L"http://user%3A:%40passwd@example.com/foo%3Fbar?q=b%26z", 25},
+ */
+ // Disabled: the resultant URL becomes "...user%253A:%2540passwd...".
+
+ // -------- omit http: --------
+ {"omit http with user name", "http://user@example.com/foo", "",
+ kFormatUrlOmitAll, net::UnescapeRule::NORMAL, L"example.com/foo", 0},
+
+ {"omit http", "http://www.google.com/", "en", kFormatUrlOmitHTTP,
+ net::UnescapeRule::NORMAL, L"www.google.com/", 0},
+
+ {"omit http with https", "https://www.google.com/", "en",
+ kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL,
+ L"https://www.google.com/", 8},
+
+ {"omit http starts with ftp.", "http://ftp.google.com/", "en",
+ kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL, L"http://ftp.google.com/",
+ 7},
+
+ // -------- omit trailing slash on bare hostname --------
+ {"omit slash when it's the entire path", "http://www.google.com/", "en",
+ kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL,
+ L"http://www.google.com", 7},
+ {"omit slash when there's a ref", "http://www.google.com/#ref", "en",
+ kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL,
+ L"http://www.google.com/#ref", 7},
+ {"omit slash when there's a query", "http://www.google.com/?", "en",
+ kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL,
+ L"http://www.google.com/?", 7},
+ {"omit slash when it's not the entire path", "http://www.google.com/foo",
+ "en", kFormatUrlOmitTrailingSlashOnBareHostname,
+ net::UnescapeRule::NORMAL, L"http://www.google.com/foo", 7},
+ {"omit slash for nonstandard URLs", "data:/", "en",
+ kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL,
+ L"data:/", 5},
+ {"omit slash for file URLs", "file:///", "en",
+ kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL,
+ L"file:///", 7},
+
+ // -------- view-source: --------
+ {"view-source", "view-source:http://xn--qcka1pmc.jp/", "ja",
+ default_format_type, net::UnescapeRule::NORMAL,
+ L"view-source:http://\x30B0\x30FC\x30B0\x30EB.jp/", 19},
+
+ {"view-source of view-source",
+ "view-source:view-source:http://xn--qcka1pmc.jp/", "ja",
+ default_format_type, net::UnescapeRule::NORMAL,
+ L"view-source:view-source:http://xn--qcka1pmc.jp/", 12},
+
+ // view-source should omit http and trailing slash where non-view-source
+ // would.
+ {"view-source omit http", "view-source:http://a.b/c", "en",
+ kFormatUrlOmitAll, net::UnescapeRule::NORMAL, L"view-source:a.b/c", 12},
+ {"view-source omit http starts with ftp.", "view-source:http://ftp.b/c",
+ "en", kFormatUrlOmitAll, net::UnescapeRule::NORMAL,
+ L"view-source:http://ftp.b/c", 19},
+ {"view-source omit slash when it's the entire path",
+ "view-source:http://a.b/", "en", kFormatUrlOmitAll,
+ net::UnescapeRule::NORMAL, L"view-source:a.b", 12},
+ };
+
+ for (size_t i = 0; i < arraysize(tests); ++i) {
+ size_t prefix_len;
+ base::string16 formatted = FormatUrl(
+ GURL(tests[i].input), tests[i].languages, tests[i].format_types,
+ tests[i].escape_rules, NULL, &prefix_len, NULL);
+ EXPECT_EQ(WideToUTF16(tests[i].output), formatted) << tests[i].description;
+ EXPECT_EQ(tests[i].prefix_len, prefix_len) << tests[i].description;
+ }
+}
+
+TEST(UrlFormatterTest, FormatUrlParsed) {
+ // No unescape case.
+ url::Parsed parsed;
+ base::string16 formatted =
+ FormatUrl(GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/"
+ "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"),
+ "ja", kFormatUrlOmitNothing, net::UnescapeRule::NONE, &parsed,
+ NULL, NULL);
+ EXPECT_EQ(WideToUTF16(
+ L"http://%E3%82%B0:%E3%83%BC@\x30B0\x30FC\x30B0\x30EB.jp:8080"
+ L"/%E3%82%B0/?q=%E3%82%B0#\x30B0"), formatted);
+ EXPECT_EQ(WideToUTF16(L"%E3%82%B0"),
+ formatted.substr(parsed.username.begin, parsed.username.len));
+ EXPECT_EQ(WideToUTF16(L"%E3%83%BC"),
+ formatted.substr(parsed.password.begin, parsed.password.len));
+ EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"),
+ formatted.substr(parsed.host.begin, parsed.host.len));
+ EXPECT_EQ(WideToUTF16(L"8080"),
+ formatted.substr(parsed.port.begin, parsed.port.len));
+ EXPECT_EQ(WideToUTF16(L"/%E3%82%B0/"),
+ formatted.substr(parsed.path.begin, parsed.path.len));
+ EXPECT_EQ(WideToUTF16(L"q=%E3%82%B0"),
+ formatted.substr(parsed.query.begin, parsed.query.len));
+ EXPECT_EQ(WideToUTF16(L"\x30B0"),
+ formatted.substr(parsed.ref.begin, parsed.ref.len));
+
+ // Unescape case.
+ formatted =
+ FormatUrl(GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/"
+ "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"),
+ "ja", kFormatUrlOmitNothing, net::UnescapeRule::NORMAL, &parsed,
+ NULL, NULL);
+ EXPECT_EQ(WideToUTF16(L"http://\x30B0:\x30FC@\x30B0\x30FC\x30B0\x30EB.jp:8080"
+ L"/\x30B0/?q=\x30B0#\x30B0"), formatted);
+ EXPECT_EQ(WideToUTF16(L"\x30B0"),
+ formatted.substr(parsed.username.begin, parsed.username.len));
+ EXPECT_EQ(WideToUTF16(L"\x30FC"),
+ formatted.substr(parsed.password.begin, parsed.password.len));
+ EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"),
+ formatted.substr(parsed.host.begin, parsed.host.len));
+ EXPECT_EQ(WideToUTF16(L"8080"),
+ formatted.substr(parsed.port.begin, parsed.port.len));
+ EXPECT_EQ(WideToUTF16(L"/\x30B0/"),
+ formatted.substr(parsed.path.begin, parsed.path.len));
+ EXPECT_EQ(WideToUTF16(L"q=\x30B0"),
+ formatted.substr(parsed.query.begin, parsed.query.len));
+ EXPECT_EQ(WideToUTF16(L"\x30B0"),
+ formatted.substr(parsed.ref.begin, parsed.ref.len));
+
+ // Omit_username_password + unescape case.
+ formatted =
+ FormatUrl(GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/"
+ "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"),
+ "ja", kFormatUrlOmitUsernamePassword, net::UnescapeRule::NORMAL,
+ &parsed, NULL, NULL);
+ EXPECT_EQ(WideToUTF16(L"http://\x30B0\x30FC\x30B0\x30EB.jp:8080"
+ L"/\x30B0/?q=\x30B0#\x30B0"), formatted);
+ EXPECT_FALSE(parsed.username.is_valid());
+ EXPECT_FALSE(parsed.password.is_valid());
+ EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"),
+ formatted.substr(parsed.host.begin, parsed.host.len));
+ EXPECT_EQ(WideToUTF16(L"8080"),
+ formatted.substr(parsed.port.begin, parsed.port.len));
+ EXPECT_EQ(WideToUTF16(L"/\x30B0/"),
+ formatted.substr(parsed.path.begin, parsed.path.len));
+ EXPECT_EQ(WideToUTF16(L"q=\x30B0"),
+ formatted.substr(parsed.query.begin, parsed.query.len));
+ EXPECT_EQ(WideToUTF16(L"\x30B0"),
+ formatted.substr(parsed.ref.begin, parsed.ref.len));
+
+ // View-source case.
+ formatted =
+ FormatUrl(GURL("view-source:http://user:passwd@host:81/path?query#ref"),
+ std::string(), kFormatUrlOmitUsernamePassword,
+ net::UnescapeRule::NORMAL, &parsed, NULL, NULL);
+ EXPECT_EQ(WideToUTF16(L"view-source:http://host:81/path?query#ref"),
+ formatted);
+ EXPECT_EQ(WideToUTF16(L"view-source:http"),
+ formatted.substr(parsed.scheme.begin, parsed.scheme.len));
+ EXPECT_FALSE(parsed.username.is_valid());
+ EXPECT_FALSE(parsed.password.is_valid());
+ EXPECT_EQ(WideToUTF16(L"host"),
+ formatted.substr(parsed.host.begin, parsed.host.len));
+ EXPECT_EQ(WideToUTF16(L"81"),
+ formatted.substr(parsed.port.begin, parsed.port.len));
+ EXPECT_EQ(WideToUTF16(L"/path"),
+ formatted.substr(parsed.path.begin, parsed.path.len));
+ EXPECT_EQ(WideToUTF16(L"query"),
+ formatted.substr(parsed.query.begin, parsed.query.len));
+ EXPECT_EQ(WideToUTF16(L"ref"),
+ formatted.substr(parsed.ref.begin, parsed.ref.len));
+
+ // omit http case.
+ formatted = FormatUrl(GURL("http://host:8000/a?b=c#d"), std::string(),
+ kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL, &parsed,
+ NULL, NULL);
+ EXPECT_EQ(WideToUTF16(L"host:8000/a?b=c#d"), formatted);
+ EXPECT_FALSE(parsed.scheme.is_valid());
+ EXPECT_FALSE(parsed.username.is_valid());
+ EXPECT_FALSE(parsed.password.is_valid());
+ EXPECT_EQ(WideToUTF16(L"host"),
+ formatted.substr(parsed.host.begin, parsed.host.len));
+ EXPECT_EQ(WideToUTF16(L"8000"),
+ formatted.substr(parsed.port.begin, parsed.port.len));
+ EXPECT_EQ(WideToUTF16(L"/a"),
+ formatted.substr(parsed.path.begin, parsed.path.len));
+ EXPECT_EQ(WideToUTF16(L"b=c"),
+ formatted.substr(parsed.query.begin, parsed.query.len));
+ EXPECT_EQ(WideToUTF16(L"d"),
+ formatted.substr(parsed.ref.begin, parsed.ref.len));
+
+ // omit http starts with ftp case.
+ formatted = FormatUrl(GURL("http://ftp.host:8000/a?b=c#d"), std::string(),
+ kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL, &parsed,
+ NULL, NULL);
+ EXPECT_EQ(WideToUTF16(L"http://ftp.host:8000/a?b=c#d"), formatted);
+ EXPECT_TRUE(parsed.scheme.is_valid());
+ EXPECT_FALSE(parsed.username.is_valid());
+ EXPECT_FALSE(parsed.password.is_valid());
+ EXPECT_EQ(WideToUTF16(L"http"),
+ formatted.substr(parsed.scheme.begin, parsed.scheme.len));
+ EXPECT_EQ(WideToUTF16(L"ftp.host"),
+ formatted.substr(parsed.host.begin, parsed.host.len));
+ EXPECT_EQ(WideToUTF16(L"8000"),
+ formatted.substr(parsed.port.begin, parsed.port.len));
+ EXPECT_EQ(WideToUTF16(L"/a"),
+ formatted.substr(parsed.path.begin, parsed.path.len));
+ EXPECT_EQ(WideToUTF16(L"b=c"),
+ formatted.substr(parsed.query.begin, parsed.query.len));
+ EXPECT_EQ(WideToUTF16(L"d"),
+ formatted.substr(parsed.ref.begin, parsed.ref.len));
+
+ // omit http starts with 'f' case.
+ formatted = FormatUrl(GURL("http://f/"), std::string(), kFormatUrlOmitHTTP,
+ net::UnescapeRule::NORMAL, &parsed, NULL, NULL);
+ EXPECT_EQ(WideToUTF16(L"f/"), formatted);
+ EXPECT_FALSE(parsed.scheme.is_valid());
+ EXPECT_FALSE(parsed.username.is_valid());
+ EXPECT_FALSE(parsed.password.is_valid());
+ EXPECT_FALSE(parsed.port.is_valid());
+ EXPECT_TRUE(parsed.path.is_valid());
+ EXPECT_FALSE(parsed.query.is_valid());
+ EXPECT_FALSE(parsed.ref.is_valid());
+ EXPECT_EQ(WideToUTF16(L"f"),
+ formatted.substr(parsed.host.begin, parsed.host.len));
+ EXPECT_EQ(WideToUTF16(L"/"),
+ formatted.substr(parsed.path.begin, parsed.path.len));
+}
+
+// Make sure that calling FormatUrl on a GURL and then converting back to a GURL
+// results in the original GURL, for each ASCII character in the path.
+TEST(UrlFormatterTest, FormatUrlRoundTripPathASCII) {
+ for (unsigned char test_char = 32; test_char < 128; ++test_char) {
+ GURL url(std::string("http://www.google.com/") +
+ static_cast<char>(test_char));
+ size_t prefix_len;
+ base::string16 formatted =
+ FormatUrl(url, std::string(), kFormatUrlOmitUsernamePassword,
+ net::UnescapeRule::NORMAL, NULL, &prefix_len, NULL);
+ EXPECT_EQ(url.spec(), GURL(formatted).spec());
+ }
+}
+
+// Make sure that calling FormatUrl on a GURL and then converting back to a GURL
+// results in the original GURL, for each escaped ASCII character in the path.
+TEST(UrlFormatterTest, FormatUrlRoundTripPathEscaped) {
+ for (unsigned char test_char = 32; test_char < 128; ++test_char) {
+ std::string original_url("http://www.google.com/");
+ original_url.push_back('%');
+ original_url.append(base::HexEncode(&test_char, 1));
+
+ GURL url(original_url);
+ size_t prefix_len;
+ base::string16 formatted =
+ FormatUrl(url, std::string(), kFormatUrlOmitUsernamePassword,
+ net::UnescapeRule::NORMAL, NULL, &prefix_len, NULL);
+ EXPECT_EQ(url.spec(), GURL(formatted).spec());
+ }
+}
+
+// Make sure that calling FormatUrl on a GURL and then converting back to a GURL
+// results in the original GURL, for each ASCII character in the query.
+TEST(UrlFormatterTest, FormatUrlRoundTripQueryASCII) {
+ for (unsigned char test_char = 32; test_char < 128; ++test_char) {
+ GURL url(std::string("http://www.google.com/?") +
+ static_cast<char>(test_char));
+ size_t prefix_len;
+ base::string16 formatted =
+ FormatUrl(url, std::string(), kFormatUrlOmitUsernamePassword,
+ net::UnescapeRule::NORMAL, NULL, &prefix_len, NULL);
+ EXPECT_EQ(url.spec(), GURL(formatted).spec());
+ }
+}
+
+// Make sure that calling FormatUrl on a GURL and then converting back to a GURL
+// only results in a different GURL for certain characters.
+TEST(UrlFormatterTest, FormatUrlRoundTripQueryEscaped) {
+ // A full list of characters which FormatURL should unescape and GURL should
+ // not escape again, when they appear in a query string.
+ const char kUnescapedCharacters[] =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~";
+ for (unsigned char test_char = 0; test_char < 128; ++test_char) {
+ std::string original_url("http://www.google.com/?");
+ original_url.push_back('%');
+ original_url.append(base::HexEncode(&test_char, 1));
+
+ GURL url(original_url);
+ size_t prefix_len;
+ base::string16 formatted =
+ FormatUrl(url, std::string(), kFormatUrlOmitUsernamePassword,
+ net::UnescapeRule::NORMAL, NULL, &prefix_len, NULL);
+
+ if (test_char &&
+ strchr(kUnescapedCharacters, static_cast<char>(test_char))) {
+ EXPECT_NE(url.spec(), GURL(formatted).spec());
+ } else {
+ EXPECT_EQ(url.spec(), GURL(formatted).spec());
+ }
+ }
+}
+
+TEST(UrlFormatterTest, FormatUrlWithOffsets) {
+ CheckAdjustedOffsets(std::string(), "en", kFormatUrlOmitNothing,
+ net::UnescapeRule::NORMAL, NULL);
+
+ const size_t basic_offsets[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25
+ };
+ CheckAdjustedOffsets("http://www.google.com/foo/", "en",
+ kFormatUrlOmitNothing, net::UnescapeRule::NORMAL,
+ basic_offsets);
+
+ const size_t omit_auth_offsets_1[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
+ };
+ CheckAdjustedOffsets("http://foo:bar@www.google.com/", "en",
+ kFormatUrlOmitUsernamePassword,
+ net::UnescapeRule::NORMAL, omit_auth_offsets_1);
+
+ const size_t omit_auth_offsets_2[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21
+ };
+ CheckAdjustedOffsets("http://foo@www.google.com/", "en",
+ kFormatUrlOmitUsernamePassword,
+ net::UnescapeRule::NORMAL, omit_auth_offsets_2);
+
+ const size_t dont_omit_auth_offsets[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos,
+ kNpos, kNpos, 11, 12, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos,
+ kNpos, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31
+ };
+ // Unescape to "http://foo\x30B0:\x30B0bar@www.google.com".
+ CheckAdjustedOffsets("http://foo%E3%82%B0:%E3%82%B0bar@www.google.com/", "en",
+ kFormatUrlOmitNothing, net::UnescapeRule::NORMAL,
+ dont_omit_auth_offsets);
+
+ const size_t view_source_offsets[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, kNpos,
+ kNpos, kNpos, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33
+ };
+ CheckAdjustedOffsets("view-source:http://foo@www.google.com/", "en",
+ kFormatUrlOmitUsernamePassword,
+ net::UnescapeRule::NORMAL, view_source_offsets);
+
+ const size_t idn_hostname_offsets_1[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos,
+ kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 12,
+ 13, 14, 15, 16, 17, 18, 19
+ };
+ // Convert punycode to "http://\x671d\x65e5\x3042\x3055\x3072.jp/foo/".
+ CheckAdjustedOffsets("http://xn--l8jvb1ey91xtjb.jp/foo/", "ja",
+ kFormatUrlOmitNothing, net::UnescapeRule::NORMAL,
+ idn_hostname_offsets_1);
+
+ const size_t idn_hostname_offsets_2[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, kNpos, kNpos, kNpos, kNpos, kNpos,
+ kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 14, 15, kNpos, kNpos, kNpos,
+ kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos,
+ kNpos, 19, 20, 21, 22, 23, 24
+ };
+ // Convert punycode to
+ // "http://test.\x89c6\x9891.\x5317\x4eac\x5927\x5b78.test/".
+ CheckAdjustedOffsets("http://test.xn--cy2a840a.xn--1lq90ic7f1rc.test/",
+ "zh-CN", kFormatUrlOmitNothing,
+ net::UnescapeRule::NORMAL, idn_hostname_offsets_2);
+
+ const size_t unescape_offsets[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, kNpos, kNpos, 26, 27, 28, 29, 30, kNpos, kNpos, kNpos,
+ kNpos, kNpos, kNpos, kNpos, kNpos, 31, kNpos, kNpos, kNpos, kNpos, kNpos,
+ kNpos, kNpos, kNpos, 32, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos,
+ kNpos, 33, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos
+ };
+ // Unescape to "http://www.google.com/foo bar/\x30B0\x30FC\x30B0\x30EB".
+ CheckAdjustedOffsets(
+ "http://www.google.com/foo%20bar/%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB",
+ "en", kFormatUrlOmitNothing, net::UnescapeRule::SPACES, unescape_offsets);
+
+ const size_t ref_offsets[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, kNpos, kNpos, 32, kNpos, kNpos,
+ 33
+ };
+ // Unescape to "http://www.google.com/foo.html#\x30B0\x30B0z".
+ CheckAdjustedOffsets(
+ "http://www.google.com/foo.html#\xE3\x82\xB0\xE3\x82\xB0z", "en",
+ kFormatUrlOmitNothing, net::UnescapeRule::NORMAL, ref_offsets);
+
+ const size_t omit_http_offsets[] = {
+ 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14
+ };
+ CheckAdjustedOffsets("http://www.google.com/", "en", kFormatUrlOmitHTTP,
+ net::UnescapeRule::NORMAL, omit_http_offsets);
+
+ const size_t omit_http_start_with_ftp_offsets[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
+ };
+ CheckAdjustedOffsets("http://ftp.google.com/", "en", kFormatUrlOmitHTTP,
+ net::UnescapeRule::NORMAL,
+ omit_http_start_with_ftp_offsets);
+
+ const size_t omit_all_offsets[] = {
+ 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, kNpos, kNpos, kNpos, kNpos,
+ 0, 1, 2, 3, 4, 5, 6, 7
+ };
+ CheckAdjustedOffsets("http://user@foo.com/", "en", kFormatUrlOmitAll,
+ net::UnescapeRule::NORMAL, omit_all_offsets);
+}
+
+} // namespace
+
+} // namespace url_formatter
diff --git a/chromium/components/user_manager.gypi b/chromium/components/user_manager.gypi
index d48b38f0946..de4297c515e 100644
--- a/chromium/components/user_manager.gypi
+++ b/chromium/components/user_manager.gypi
@@ -73,6 +73,7 @@
'dependencies': [
'<(DEPTH)/base/base.gyp:base',
'<(DEPTH)/base/base.gyp:test_support_base',
+ '<(DEPTH)/skia/skia.gyp:skia',
'<(DEPTH)/testing/gmock.gyp:gmock',
'<(DEPTH)/testing/gtest.gyp:gtest',
'user_manager',
diff --git a/chromium/components/user_prefs.gypi b/chromium/components/user_prefs.gypi
index 3554d0d9ae9..cfeff21a5af 100644
--- a/chromium/components/user_prefs.gypi
+++ b/chromium/components/user_prefs.gypi
@@ -23,5 +23,77 @@
'user_prefs/user_prefs_export.h',
],
},
+ {
+ 'target_name': 'user_prefs_tracked',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ ],
+ 'sources': [
+ 'user_prefs/tracked/device_id.h',
+ 'user_prefs/tracked/device_id_mac.cc',
+ 'user_prefs/tracked/device_id_stub.cc',
+ 'user_prefs/tracked/device_id_win.cc',
+ 'user_prefs/tracked/dictionary_hash_store_contents.cc',
+ 'user_prefs/tracked/dictionary_hash_store_contents.h',
+ 'user_prefs/tracked/hash_store_contents.h',
+ 'user_prefs/tracked/interceptable_pref_filter.cc',
+ 'user_prefs/tracked/interceptable_pref_filter.h',
+ 'user_prefs/tracked/pref_hash_calculator.cc',
+ 'user_prefs/tracked/pref_hash_calculator.h',
+ 'user_prefs/tracked/pref_hash_filter.cc',
+ 'user_prefs/tracked/pref_hash_filter.h',
+ 'user_prefs/tracked/pref_hash_store.h',
+ 'user_prefs/tracked/pref_hash_store_impl.cc',
+ 'user_prefs/tracked/pref_hash_store_impl.h',
+ 'user_prefs/tracked/pref_hash_store_transaction.h',
+ 'user_prefs/tracked/pref_names.cc',
+ 'user_prefs/tracked/pref_names.h',
+ 'user_prefs/tracked/pref_service_hash_store_contents.cc',
+ 'user_prefs/tracked/pref_service_hash_store_contents.h',
+ 'user_prefs/tracked/segregated_pref_store.cc',
+ 'user_prefs/tracked/segregated_pref_store.h',
+ 'user_prefs/tracked/tracked_atomic_preference.cc',
+ 'user_prefs/tracked/tracked_atomic_preference.h',
+ 'user_prefs/tracked/tracked_preference.h',
+ 'user_prefs/tracked/tracked_preference_helper.cc',
+ 'user_prefs/tracked/tracked_preference_helper.h',
+ 'user_prefs/tracked/tracked_preference_validation_delegate.h',
+ 'user_prefs/tracked/tracked_preferences_migration.cc',
+ 'user_prefs/tracked/tracked_preferences_migration.h',
+ 'user_prefs/tracked/tracked_split_preference.cc',
+ 'user_prefs/tracked/tracked_split_preference.h',
+ ],
+ 'conditions': [
+ ['OS=="win" or (OS=="mac" and OS!="ios")', {
+ 'sources!': [
+ 'user_prefs/tracked/device_id_stub.cc',
+ ],
+ }],
+ ['OS=="ios"', {
+ 'sources!': [
+ 'user_prefs/tracked/device_id_mac.cc',
+ ],
+ }],
+ ],
+
+ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+ 'msvs_disabled_warnings': [4267, ],
+ },
+ {
+ 'target_name': 'user_prefs_tracked_test_support',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ ],
+ 'sources': [
+ 'user_prefs/tracked/mock_validation_delegate.cc',
+ 'user_prefs/tracked/mock_validation_delegate.h',
+ ],
+ },
],
}
diff --git a/chromium/components/user_prefs/BUILD.gn b/chromium/components/user_prefs/BUILD.gn
new file mode 100644
index 00000000000..3d777d23325
--- /dev/null
+++ b/chromium/components/user_prefs/BUILD.gn
@@ -0,0 +1,18 @@
+# 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.
+
+component("user_prefs") {
+ sources = [
+ "user_prefs.cc",
+ "user_prefs.h",
+ "user_prefs_export.h",
+ ]
+
+ defines = [ "USER_PREFS_IMPLEMENTATION" ]
+
+ deps = [
+ "//base",
+ "//base:prefs",
+ ]
+}
diff --git a/chromium/components/user_prefs/DEPS b/chromium/components/user_prefs/DEPS
new file mode 100644
index 00000000000..9ca65e36d8e
--- /dev/null
+++ b/chromium/components/user_prefs/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ # user_prefs can be used on all platforms, including iOS. Do not allow
+ # platform-specific dependencies.
+ "-content",
+ "-ios",
+]
diff --git a/chromium/components/user_prefs/OWNERS b/chromium/components/user_prefs/OWNERS
new file mode 100644
index 00000000000..2d870381cb7
--- /dev/null
+++ b/chromium/components/user_prefs/OWNERS
@@ -0,0 +1,4 @@
+battre@chromium.org
+bauerb@chromium.org
+gab@chromium.org
+pam@chromium.org
diff --git a/chromium/components/user_prefs/README b/chromium/components/user_prefs/README
new file mode 100644
index 00000000000..a7ca50936d2
--- /dev/null
+++ b/chromium/components/user_prefs/README
@@ -0,0 +1,8 @@
+The //components/user_pref component provides:
+
+a) The UserPrefs class, where components dependent on looking up
+preferences associated with users can look them up by
+content::BrowserContext.
+
+b) A place for PrefRegistrySyncable to live, where it can be used by
+components that need to register preferences associated with users.
diff --git a/chromium/components/user_prefs/tracked/BUILD.gn b/chromium/components/user_prefs/tracked/BUILD.gn
new file mode 100644
index 00000000000..e749217357d
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/BUILD.gn
@@ -0,0 +1,94 @@
+# 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.
+
+static_library("user_prefs_tracked") {
+ sources = [
+ "device_id.h",
+ "device_id_mac.cc",
+ "device_id_stub.cc",
+ "device_id_win.cc",
+ "dictionary_hash_store_contents.cc",
+ "dictionary_hash_store_contents.h",
+ "hash_store_contents.h",
+ "interceptable_pref_filter.cc",
+ "interceptable_pref_filter.h",
+ "pref_hash_calculator.cc",
+ "pref_hash_calculator.h",
+ "pref_hash_filter.cc",
+ "pref_hash_filter.h",
+ "pref_hash_store.h",
+ "pref_hash_store_impl.cc",
+ "pref_hash_store_impl.h",
+ "pref_hash_store_transaction.h",
+ "pref_names.cc",
+ "pref_names.h",
+ "pref_service_hash_store_contents.cc",
+ "pref_service_hash_store_contents.h",
+ "segregated_pref_store.cc",
+ "segregated_pref_store.h",
+ "tracked_atomic_preference.cc",
+ "tracked_atomic_preference.h",
+ "tracked_preference.h",
+ "tracked_preference_helper.cc",
+ "tracked_preference_helper.h",
+ "tracked_preference_validation_delegate.h",
+ "tracked_preferences_migration.cc",
+ "tracked_preferences_migration.h",
+ "tracked_split_preference.cc",
+ "tracked_split_preference.h",
+ ]
+
+ if (is_win || (is_mac && !is_ios)) {
+ sources -= [ "device_id_stub.cc" ]
+ }
+
+ if (is_ios) {
+ sources -= [ "device_id_mac.cc" ]
+ }
+
+ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+ configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+
+ deps = [
+ "//base:base",
+ "//base:prefs",
+ "//crypto:crypto",
+ "//components/pref_registry",
+ ]
+}
+
+source_set("user_prefs_tracked_test_support") {
+ testonly = true
+ sources = [
+ "mock_validation_delegate.cc",
+ "mock_validation_delegate.h",
+ ]
+
+ deps = [
+ ":user_prefs_tracked",
+ "//base:base",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "device_id_unittest.cc",
+ "pref_hash_calculator_unittest.cc",
+ "pref_hash_filter_unittest.cc",
+ "pref_hash_store_impl_unittest.cc",
+ "pref_service_hash_store_contents_unittest.cc",
+ "segregated_pref_store_unittest.cc",
+ "tracked_preferences_migration_unittest.cc",
+ ]
+
+ deps = [
+ ":user_prefs_tracked",
+ ":user_prefs_tracked_test_support",
+ "//base:base",
+ "//base:prefs",
+ "//base:prefs_test_support",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/user_prefs/tracked/DEPS b/chromium/components/user_prefs/tracked/DEPS
new file mode 100644
index 00000000000..6ccb05e9fab
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+components/pref_registry",
+ "+crypto/hmac.h",
+]
diff --git a/chromium/components/user_prefs/tracked/OWNERS b/chromium/components/user_prefs/tracked/OWNERS
new file mode 100644
index 00000000000..2845b0f366d
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/OWNERS
@@ -0,0 +1,2 @@
+bauerb@chromium.org
+gab@chromium.org
diff --git a/chromium/components/user_prefs/tracked/device_id.h b/chromium/components/user_prefs/tracked/device_id.h
new file mode 100644
index 00000000000..2d6d1b8e8b6
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/device_id.h
@@ -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.
+
+#ifndef COMPONENTS_USER_PREFS_TRACKED_DEVICE_ID_H_
+#define COMPONENTS_USER_PREFS_TRACKED_DEVICE_ID_H_
+
+#include <string>
+
+enum class MachineIdStatus {
+ SUCCESS = 0,
+ FAILURE, // Returned if attempt to obtain a machine-specific ID fails.
+ NOT_IMPLEMENTED // Returned if the method for obtaining a machine-specific ID
+ // is not implemented for the system.
+};
+
+// Populates |machine_id| with a deterministic ID for this machine. |machine_id|
+// must not be null. Returns |FAILURE| if a machine ID cannot be obtained or
+// |NOT_IMPLEMENTED| on systems for which this feature is not supported (in both
+// cases |machine_id| is left untouched).
+MachineIdStatus GetDeterministicMachineSpecificId(std::string* machine_id);
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_DEVICE_ID_H_
diff --git a/chromium/components/user_prefs/tracked/device_id_mac.cc b/chromium/components/user_prefs/tracked/device_id_mac.cc
new file mode 100644
index 00000000000..bd5ce805647
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/device_id_mac.cc
@@ -0,0 +1,32 @@
+// 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/user_prefs/tracked/device_id.h"
+
+#include <IOKit/IOKitLib.h>
+
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/mac/scoped_ioobject.h"
+#include "base/strings/sys_string_conversions.h"
+
+MachineIdStatus GetDeterministicMachineSpecificId(std::string* machine_id) {
+ base::mac::ScopedIOObject<io_service_t> platform_expert(
+ IOServiceGetMatchingService(kIOMasterPortDefault,
+ IOServiceMatching("IOPlatformExpertDevice")));
+ if (!platform_expert.get())
+ return MachineIdStatus::FAILURE;
+
+ base::ScopedCFTypeRef<CFTypeRef> uuid(IORegistryEntryCreateCFProperty(
+ platform_expert, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0));
+ if (!uuid.get())
+ return MachineIdStatus::FAILURE;
+
+ CFStringRef uuid_string = base::mac::CFCast<CFStringRef>(uuid);
+ if (!uuid_string)
+ return MachineIdStatus::FAILURE;
+
+ *machine_id = base::SysCFStringRefToUTF8(uuid_string);
+ return MachineIdStatus::SUCCESS;
+}
diff --git a/chromium/components/user_prefs/tracked/device_id_stub.cc b/chromium/components/user_prefs/tracked/device_id_stub.cc
new file mode 100644
index 00000000000..07ffb944fe5
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/device_id_stub.cc
@@ -0,0 +1,11 @@
+// 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/user_prefs/tracked/device_id.h"
+#include "base/logging.h"
+
+MachineIdStatus GetDeterministicMachineSpecificId(std::string* machine_id) {
+ DCHECK(machine_id);
+ return MachineIdStatus::NOT_IMPLEMENTED;
+}
diff --git a/chromium/components/user_prefs/tracked/device_id_unittest.cc b/chromium/components/user_prefs/tracked/device_id_unittest.cc
new file mode 100644
index 00000000000..badc02bae67
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/device_id_unittest.cc
@@ -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.
+
+#include "components/user_prefs/tracked/device_id.h"
+
+#include "build/build_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(GetDeterministicMachineSpecificIdTest, IsDeterministic) {
+ std::string first_machine_id;
+ std::string second_machine_id;
+
+ const MachineIdStatus kExpectedStatus =
+#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
+ MachineIdStatus::SUCCESS;
+#else
+ MachineIdStatus::NOT_IMPLEMENTED;
+#endif
+
+ ASSERT_EQ(kExpectedStatus,
+ GetDeterministicMachineSpecificId(&first_machine_id));
+ ASSERT_EQ(kExpectedStatus,
+ GetDeterministicMachineSpecificId(&second_machine_id));
+
+ // The reason for using |EXPECT_TRUE| with one argument instead of |EXPECT_EQ|
+ // with two arguments is a compiler bug in gcc that results in a "converting
+ // 'false' to pointer type" error when the first argument to |EXPECT_EQ| is a
+ // compile-time const false value. See also the following bug reports:
+ // https://code.google.com/p/googletest/issues/detail?id=322
+ // https://code.google.com/p/googletest/issues/detail?id=458
+ EXPECT_TRUE((kExpectedStatus == MachineIdStatus::SUCCESS) ==
+ !first_machine_id.empty());
+ EXPECT_EQ(first_machine_id, second_machine_id);
+}
diff --git a/chromium/components/user_prefs/tracked/device_id_win.cc b/chromium/components/user_prefs/tracked/device_id_win.cc
new file mode 100644
index 00000000000..579d509dd17
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/device_id_win.cc
@@ -0,0 +1,71 @@
+// 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/user_prefs/tracked/device_id.h"
+
+#include <windows.h>
+#include <sddl.h> // For ConvertSidToStringSidA.
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+
+MachineIdStatus GetDeterministicMachineSpecificId(std::string* machine_id) {
+ DCHECK(machine_id);
+
+ wchar_t computer_name[MAX_COMPUTERNAME_LENGTH + 1] = {};
+ DWORD computer_name_size = arraysize(computer_name);
+
+ if (!::GetComputerNameW(computer_name, &computer_name_size))
+ return MachineIdStatus::FAILURE;
+
+ DWORD sid_size = SECURITY_MAX_SID_SIZE;
+ char sid_buffer[SECURITY_MAX_SID_SIZE];
+ SID* sid = reinterpret_cast<SID*>(sid_buffer);
+ DWORD domain_size = 128; // Will expand below if needed.
+ scoped_ptr<wchar_t[]> domain_buffer(new wchar_t[domain_size]);
+ SID_NAME_USE sid_name_use;
+
+ // Although the fifth argument to |LookupAccountNameW()|,
+ // |ReferencedDomainName|, is annotated as |_Out_opt_|, if a null
+ // value is passed in, zero is returned and |GetLastError()| will
+ // return |ERROR_INSUFFICIENT_BUFFER| (assuming that nothing else went
+ // wrong). In order to ensure that the call to |LookupAccountNameW()|
+ // has succeeded, it is necessary to include the following logic and
+ // obtain the domain name.
+ if (!::LookupAccountNameW(nullptr, computer_name, sid, &sid_size,
+ domain_buffer.get(), &domain_size, &sid_name_use)) {
+ // If the initial size of |domain_buffer| was too small, the
+ // required size is now found in |domain_size|. Resize and try
+ // again.
+ if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ return MachineIdStatus::FAILURE;
+
+ domain_buffer.reset(new wchar_t[domain_size]);
+ if (!::LookupAccountNameW(nullptr, computer_name, sid, &sid_size,
+ domain_buffer.get(), &domain_size,
+ &sid_name_use)) {
+ return MachineIdStatus::FAILURE;
+ }
+ }
+
+ // Ensure that the correct type of SID was obtained. The
+ // |LookupAccountNameW()| function seems to always return
+ // |SidTypeDomain| instead of |SidTypeComputer| when the computer name
+ // is passed in as its second argument and therefore both enum values
+ // will be considered acceptable. If the computer name and user name
+ // coincide, |LookupAccountNameW()| seems to always return the machine
+ // SID and set the returned enum to |SidTypeDomain|.
+ DCHECK(sid_name_use == SID_NAME_USE::SidTypeComputer ||
+ sid_name_use == SID_NAME_USE::SidTypeDomain);
+
+ char* sid_string = nullptr;
+ if (!::ConvertSidToStringSidA(sid, &sid_string))
+ return MachineIdStatus::FAILURE;
+
+ *machine_id = sid_string;
+ ::LocalFree(sid_string);
+
+ return MachineIdStatus::SUCCESS;
+}
diff --git a/chromium/components/user_prefs/tracked/dictionary_hash_store_contents.cc b/chromium/components/user_prefs/tracked/dictionary_hash_store_contents.cc
new file mode 100644
index 00000000000..ba791278c07
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/dictionary_hash_store_contents.cc
@@ -0,0 +1,94 @@
+// Copyright (c) 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/user_prefs/tracked/dictionary_hash_store_contents.h"
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/prefs/persistent_pref_store.h"
+#include "base/values.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+
+namespace {
+
+const char kPreferenceMACs[] = "protection.macs";
+const char kSuperMACPref[] = "protection.super_mac";
+
+class MutablePreferenceMacDictionary
+ : public HashStoreContents::MutableDictionary {
+ public:
+ explicit MutablePreferenceMacDictionary(base::DictionaryValue* storage);
+
+ // MutableDictionary implementation
+ base::DictionaryValue* operator->() override;
+
+ private:
+ base::DictionaryValue* storage_;
+
+ DISALLOW_COPY_AND_ASSIGN(MutablePreferenceMacDictionary);
+};
+
+MutablePreferenceMacDictionary::MutablePreferenceMacDictionary(
+ base::DictionaryValue* storage)
+ : storage_(storage) {
+}
+
+base::DictionaryValue* MutablePreferenceMacDictionary::operator->() {
+ base::DictionaryValue* mac_dictionary = NULL;
+
+ if (!storage_->GetDictionary(kPreferenceMACs, &mac_dictionary)) {
+ mac_dictionary = new base::DictionaryValue;
+ storage_->Set(kPreferenceMACs, mac_dictionary);
+ }
+
+ return mac_dictionary;
+}
+
+} // namespace
+
+DictionaryHashStoreContents::DictionaryHashStoreContents(
+ base::DictionaryValue* storage)
+ : storage_(storage) {
+}
+
+// static
+void DictionaryHashStoreContents::RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterDictionaryPref(kPreferenceMACs);
+ registry->RegisterStringPref(kSuperMACPref, std::string());
+}
+
+std::string DictionaryHashStoreContents::hash_store_id() const {
+ return "";
+}
+
+void DictionaryHashStoreContents::Reset() {
+ storage_->Remove(kPreferenceMACs, NULL);
+}
+
+bool DictionaryHashStoreContents::IsInitialized() const {
+ return storage_->GetDictionary(kPreferenceMACs, NULL);
+}
+
+const base::DictionaryValue* DictionaryHashStoreContents::GetContents() const {
+ const base::DictionaryValue* mac_dictionary = NULL;
+ storage_->GetDictionary(kPreferenceMACs, &mac_dictionary);
+ return mac_dictionary;
+}
+
+scoped_ptr<HashStoreContents::MutableDictionary>
+DictionaryHashStoreContents::GetMutableContents() {
+ return scoped_ptr<MutableDictionary>(
+ new MutablePreferenceMacDictionary(storage_));
+}
+
+std::string DictionaryHashStoreContents::GetSuperMac() const {
+ std::string super_mac_string;
+ storage_->GetString(kSuperMACPref, &super_mac_string);
+ return super_mac_string;
+}
+
+void DictionaryHashStoreContents::SetSuperMac(const std::string& super_mac) {
+ storage_->SetString(kSuperMACPref, super_mac);
+}
diff --git a/chromium/components/user_prefs/tracked/dictionary_hash_store_contents.h b/chromium/components/user_prefs/tracked/dictionary_hash_store_contents.h
new file mode 100644
index 00000000000..09178e7f173
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/dictionary_hash_store_contents.h
@@ -0,0 +1,48 @@
+// 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_USER_PREFS_TRACKED_DICTIONARY_HASH_STORE_CONTENTS_H_
+#define COMPONENTS_USER_PREFS_TRACKED_DICTIONARY_HASH_STORE_CONTENTS_H_
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "components/user_prefs/tracked/hash_store_contents.h"
+
+namespace base {
+class DictionaryValue;
+} // namespace base
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+} // namespace user_prefs
+
+// Implements HashStoreContents by storing MACs in a DictionaryValue. The
+// DictionaryValue is presumed to be the contents of a PrefStore.
+// RegisterProfilePrefs() may be used to register all of the preferences used by
+// this object.
+class DictionaryHashStoreContents : public HashStoreContents {
+ public:
+ // Constructs a DictionaryHashStoreContents that reads from and writes to
+ // |storage|.
+ explicit DictionaryHashStoreContents(base::DictionaryValue* storage);
+
+ // Registers required preferences.
+ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+ // HashStoreContents implementation
+ std::string hash_store_id() const override;
+ void Reset() override;
+ bool IsInitialized() const override;
+ const base::DictionaryValue* GetContents() const override;
+ scoped_ptr<MutableDictionary> GetMutableContents() override;
+ std::string GetSuperMac() const override;
+ void SetSuperMac(const std::string& super_mac) override;
+
+ private:
+ base::DictionaryValue* storage_;
+
+ DISALLOW_COPY_AND_ASSIGN(DictionaryHashStoreContents);
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_DICTIONARY_HASH_STORE_CONTENTS_H_
diff --git a/chromium/components/user_prefs/tracked/hash_store_contents.h b/chromium/components/user_prefs/tracked/hash_store_contents.h
new file mode 100644
index 00000000000..94131ab77e8
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/hash_store_contents.h
@@ -0,0 +1,63 @@
+// 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_USER_PREFS_TRACKED_HASH_STORE_CONTENTS_H_
+#define COMPONENTS_USER_PREFS_TRACKED_HASH_STORE_CONTENTS_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+class DictionaryValue;
+} // namespace base
+
+// Provides access to the contents of a preference hash store. The store
+// contains the following data:
+// Contents: a client-defined dictionary that should map preference names to
+// MACs.
+// Version: a client-defined version number for the format of Contents.
+// Super MAC: a MAC that authenticates the entirety of Contents.
+// Legacy hash stores may have an ID that was incorporated into MAC
+// calculations. The ID, if any, is available via |hash_store_id()|.
+class HashStoreContents {
+ public:
+ // Used to modify a DictionaryValue stored in the preference hash store. The
+ // MutableDictionary should be destroyed when modifications are complete in
+ // order to allow them to be committed to the underlying storage.
+ class MutableDictionary {
+ public:
+ virtual ~MutableDictionary() {}
+ // Returns the DictionaryValue, which will be created if it does not already
+ // exist.
+ virtual base::DictionaryValue* operator->() = 0;
+ };
+
+ virtual ~HashStoreContents() {}
+
+ // Returns the hash-store ID. May be empty.
+ virtual std::string hash_store_id() const = 0;
+
+ // Discards all data related to this hash store.
+ virtual void Reset() = 0;
+
+ // Indicates whether any data is currently stored for this hash store.
+ virtual bool IsInitialized() const = 0;
+
+ // Retrieves the contents of this hash store. May return NULL if the hash
+ // store has not been initialized.
+ virtual const base::DictionaryValue* GetContents() const = 0;
+
+ // Provides mutable access to the contents of this hash store.
+ virtual scoped_ptr<MutableDictionary> GetMutableContents() = 0;
+
+ // Retrieves the super MAC value previously stored by SetSuperMac. May be
+ // empty if no super MAC has been stored.
+ virtual std::string GetSuperMac() const = 0;
+
+ // Stores a super MAC value for this hash store.
+ virtual void SetSuperMac(const std::string& super_mac) = 0;
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_HASH_STORE_CONTENTS_H_
diff --git a/chromium/components/user_prefs/tracked/interceptable_pref_filter.cc b/chromium/components/user_prefs/tracked/interceptable_pref_filter.cc
new file mode 100644
index 00000000000..180ee7e993c
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/interceptable_pref_filter.cc
@@ -0,0 +1,39 @@
+// 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/user_prefs/tracked/interceptable_pref_filter.h"
+
+#include "base/bind.h"
+
+InterceptablePrefFilter::InterceptablePrefFilter() {
+}
+InterceptablePrefFilter::~InterceptablePrefFilter() {
+}
+
+void InterceptablePrefFilter::FilterOnLoad(
+ const PostFilterOnLoadCallback& post_filter_on_load_callback,
+ scoped_ptr<base::DictionaryValue> pref_store_contents) {
+ if (filter_on_load_interceptor_.is_null()) {
+ FinalizeFilterOnLoad(post_filter_on_load_callback,
+ pref_store_contents.Pass(), false);
+ } else {
+ // Note, in practice (in the implementation as it was in May 2014) it would
+ // be okay to pass an unretained |this| pointer below, but in order to avoid
+ // having to augment the API everywhere to explicitly enforce the ownership
+ // model as it happens to currently be: make the relationship simpler by
+ // weakly binding the FinalizeFilterOnLoadCallback below to |this|.
+ const FinalizeFilterOnLoadCallback finalize_filter_on_load(
+ base::Bind(&InterceptablePrefFilter::FinalizeFilterOnLoad, AsWeakPtr(),
+ post_filter_on_load_callback));
+ filter_on_load_interceptor_.Run(finalize_filter_on_load,
+ pref_store_contents.Pass());
+ filter_on_load_interceptor_.Reset();
+ }
+}
+
+void InterceptablePrefFilter::InterceptNextFilterOnLoad(
+ const FilterOnLoadInterceptor& filter_on_load_interceptor) {
+ DCHECK(filter_on_load_interceptor_.is_null());
+ filter_on_load_interceptor_ = filter_on_load_interceptor;
+}
diff --git a/chromium/components/user_prefs/tracked/interceptable_pref_filter.h b/chromium/components/user_prefs/tracked/interceptable_pref_filter.h
new file mode 100644
index 00000000000..58021df319c
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/interceptable_pref_filter.h
@@ -0,0 +1,64 @@
+// 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_USER_PREFS_TRACKED_INTERCEPTABLE_PREF_FILTER_H_
+#define COMPONENTS_USER_PREFS_TRACKED_INTERCEPTABLE_PREF_FILTER_H_
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "base/prefs/pref_filter.h"
+#include "base/values.h"
+
+// A partial implementation of a PrefFilter whose FilterOnLoad call may be
+// intercepted by a FilterOnLoadInterceptor. Implementations of
+// InterceptablePrefFilter are expected to override FinalizeFilterOnLoad rather
+// than re-overriding FilterOnLoad.
+class InterceptablePrefFilter
+ : public PrefFilter,
+ public base::SupportsWeakPtr<InterceptablePrefFilter> {
+ public:
+ // A callback to be invoked by a FilterOnLoadInterceptor when its ready to
+ // hand back the |prefs| it was handed for early filtering. |prefs_altered|
+ // indicates whether the |prefs| were actually altered by the
+ // FilterOnLoadInterceptor before being handed back.
+ typedef base::Callback<void(scoped_ptr<base::DictionaryValue> prefs,
+ bool prefs_altered)> FinalizeFilterOnLoadCallback;
+
+ // A callback to be invoked from FilterOnLoad. It takes ownership of prefs
+ // and may modify them before handing them back to this
+ // InterceptablePrefFilter via |finalize_filter_on_load|.
+ typedef base::Callback<void(
+ const FinalizeFilterOnLoadCallback& finalize_filter_on_load,
+ scoped_ptr<base::DictionaryValue> prefs)> FilterOnLoadInterceptor;
+
+ InterceptablePrefFilter();
+ ~InterceptablePrefFilter() override;
+
+ // PrefFilter partial implementation.
+ void FilterOnLoad(
+ const PostFilterOnLoadCallback& post_filter_on_load_callback,
+ scoped_ptr<base::DictionaryValue> pref_store_contents) override;
+
+ // Registers |filter_on_load_interceptor| to intercept the next FilterOnLoad
+ // event. At most one FilterOnLoadInterceptor should be registered per
+ // PrefFilter.
+ void InterceptNextFilterOnLoad(
+ const FilterOnLoadInterceptor& filter_on_load_interceptor);
+
+ private:
+ // Does any extra filtering required by the implementation of this
+ // InterceptablePrefFilter and hands back the |pref_store_contents| to the
+ // initial caller of FilterOnLoad.
+ virtual void FinalizeFilterOnLoad(
+ const PostFilterOnLoadCallback& post_filter_on_load_callback,
+ scoped_ptr<base::DictionaryValue> pref_store_contents,
+ bool prefs_altered) = 0;
+
+ // Callback to be invoked only once (and subsequently reset) on the next
+ // FilterOnLoad event. It will be allowed to modify the |prefs| handed to
+ // FilterOnLoad before handing them back to this PrefHashFilter.
+ FilterOnLoadInterceptor filter_on_load_interceptor_;
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_INTERCEPTABLE_PREF_FILTER_H_
diff --git a/chromium/components/user_prefs/tracked/mock_validation_delegate.cc b/chromium/components/user_prefs/tracked/mock_validation_delegate.cc
new file mode 100644
index 00000000000..d2936af55be
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/mock_validation_delegate.cc
@@ -0,0 +1,58 @@
+// 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/user_prefs/tracked/mock_validation_delegate.h"
+
+MockValidationDelegate::MockValidationDelegate() {
+}
+
+MockValidationDelegate::~MockValidationDelegate() {
+}
+
+size_t MockValidationDelegate::CountValidationsOfState(
+ PrefHashStoreTransaction::ValueState value_state) const {
+ size_t count = 0;
+ for (size_t i = 0; i < validations_.size(); ++i) {
+ if (validations_[i].value_state == value_state)
+ ++count;
+ }
+ return count;
+}
+
+const MockValidationDelegate::ValidationEvent*
+MockValidationDelegate::GetEventForPath(const std::string& pref_path) const {
+ for (size_t i = 0; i < validations_.size(); ++i) {
+ if (validations_[i].pref_path == pref_path)
+ return &validations_[i];
+ }
+ return NULL;
+}
+
+void MockValidationDelegate::OnAtomicPreferenceValidation(
+ const std::string& pref_path,
+ const base::Value* value,
+ PrefHashStoreTransaction::ValueState value_state,
+ bool is_personal) {
+ RecordValidation(pref_path, value_state, is_personal,
+ PrefHashFilter::TRACKING_STRATEGY_ATOMIC);
+}
+
+void MockValidationDelegate::OnSplitPreferenceValidation(
+ const std::string& pref_path,
+ const base::DictionaryValue* dict_value,
+ const std::vector<std::string>& invalid_keys,
+ PrefHashStoreTransaction::ValueState value_state,
+ bool is_personal) {
+ RecordValidation(pref_path, value_state, is_personal,
+ PrefHashFilter::TRACKING_STRATEGY_SPLIT);
+}
+
+void MockValidationDelegate::RecordValidation(
+ const std::string& pref_path,
+ PrefHashStoreTransaction::ValueState value_state,
+ bool is_personal,
+ PrefHashFilter::PrefTrackingStrategy strategy) {
+ validations_.push_back(
+ ValidationEvent(pref_path, value_state, is_personal, strategy));
+}
diff --git a/chromium/components/user_prefs/tracked/mock_validation_delegate.h b/chromium/components/user_prefs/tracked/mock_validation_delegate.h
new file mode 100644
index 00000000000..be2051e3c14
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/mock_validation_delegate.h
@@ -0,0 +1,74 @@
+// 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_USER_PREFS_TRACKED_MOCK_VALIDATION_DELEGATE_H_
+#define COMPONENTS_USER_PREFS_TRACKED_MOCK_VALIDATION_DELEGATE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "components/user_prefs/tracked/pref_hash_filter.h"
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+#include "components/user_prefs/tracked/tracked_preference_validation_delegate.h"
+
+// A mock tracked preference validation delegate for use by tests.
+class MockValidationDelegate : public TrackedPreferenceValidationDelegate {
+ public:
+ struct ValidationEvent {
+ ValidationEvent(const std::string& path,
+ PrefHashStoreTransaction::ValueState state,
+ bool is_personal,
+ PrefHashFilter::PrefTrackingStrategy tracking_strategy)
+ : pref_path(path),
+ value_state(state),
+ is_personal(is_personal),
+ strategy(tracking_strategy) {}
+
+ std::string pref_path;
+ PrefHashStoreTransaction::ValueState value_state;
+ bool is_personal;
+ PrefHashFilter::PrefTrackingStrategy strategy;
+ };
+
+ MockValidationDelegate();
+ ~MockValidationDelegate() override;
+
+ // Returns the number of recorded validations.
+ size_t recorded_validations_count() const { return validations_.size(); }
+
+ // Returns the number of validations of a given value state.
+ size_t CountValidationsOfState(
+ PrefHashStoreTransaction::ValueState value_state) const;
+
+ // Returns the event for the preference with a given path.
+ const ValidationEvent* GetEventForPath(const std::string& pref_path) const;
+
+ // TrackedPreferenceValidationDelegate implementation.
+ void OnAtomicPreferenceValidation(
+ const std::string& pref_path,
+ const base::Value* value,
+ PrefHashStoreTransaction::ValueState value_state,
+ bool is_personal) override;
+ void OnSplitPreferenceValidation(
+ const std::string& pref_path,
+ const base::DictionaryValue* dict_value,
+ const std::vector<std::string>& invalid_keys,
+ PrefHashStoreTransaction::ValueState value_state,
+ bool is_personal) override;
+
+ private:
+ // Adds a new validation event.
+ void RecordValidation(const std::string& pref_path,
+ PrefHashStoreTransaction::ValueState value_state,
+ bool is_personal,
+ PrefHashFilter::PrefTrackingStrategy strategy);
+
+ std::vector<ValidationEvent> validations_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockValidationDelegate);
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_MOCK_VALIDATION_DELEGATE_H_
diff --git a/chromium/components/user_prefs/tracked/pref_hash_calculator.cc b/chromium/components/user_prefs/tracked/pref_hash_calculator.cc
new file mode 100644
index 00000000000..3d5b7fa37c2
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_calculator.cc
@@ -0,0 +1,125 @@
+// 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/user_prefs/tracked/pref_hash_calculator.h"
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/json/json_string_value_serializer.h"
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "crypto/hmac.h"
+
+namespace {
+
+// Calculates an HMAC of |message| using |key|, encoded as a hexadecimal string.
+std::string GetDigestString(const std::string& key,
+ const std::string& message) {
+ crypto::HMAC hmac(crypto::HMAC::SHA256);
+ std::vector<uint8> digest(hmac.DigestLength());
+ if (!hmac.Init(key) || !hmac.Sign(message, &digest[0], digest.size())) {
+ NOTREACHED();
+ return std::string();
+ }
+ return base::HexEncode(&digest[0], digest.size());
+}
+
+// Verifies that |digest_string| is a valid HMAC of |message| using |key|.
+// |digest_string| must be encoded as a hexadecimal string.
+bool VerifyDigestString(const std::string& key,
+ const std::string& message,
+ const std::string& digest_string) {
+ crypto::HMAC hmac(crypto::HMAC::SHA256);
+ std::vector<uint8> digest;
+ return base::HexStringToBytes(digest_string, &digest) && hmac.Init(key) &&
+ hmac.Verify(message,
+ base::StringPiece(reinterpret_cast<char*>(&digest[0]),
+ digest.size()));
+}
+
+// Renders |value| as a string. |value| may be NULL, in which case the result
+// is an empty string. This method can be expensive and its result should be
+// re-used rather than recomputed where possible.
+std::string ValueAsString(const base::Value* value) {
+ // Dictionary values may contain empty lists and sub-dictionaries. Make a
+ // deep copy with those removed to make the hash more stable.
+ const base::DictionaryValue* dict_value;
+ scoped_ptr<base::DictionaryValue> canonical_dict_value;
+ if (value && value->GetAsDictionary(&dict_value)) {
+ canonical_dict_value = dict_value->DeepCopyWithoutEmptyChildren();
+ value = canonical_dict_value.get();
+ }
+
+ std::string value_as_string;
+ if (value) {
+ JSONStringValueSerializer serializer(&value_as_string);
+ serializer.Serialize(*value);
+ }
+
+ return value_as_string;
+}
+
+// Concatenates |device_id|, |path|, and |value_as_string| to give the hash
+// input.
+std::string GetMessage(const std::string& device_id,
+ const std::string& path,
+ const std::string& value_as_string) {
+ std::string message;
+ message.reserve(device_id.size() + path.size() + value_as_string.size());
+ message.append(device_id);
+ message.append(path);
+ message.append(value_as_string);
+ return message;
+}
+
+// Generates a device ID based on the input device ID. The derived device ID has
+// no useful properties beyond those of the input device ID except that it is
+// consistent with previous implementations.
+// TODO(gab): Remove this once UMA reports for
+// Settings.TrackedPreferenceMigratedLegacyDeviceId become insignificant.
+std::string GenerateDeviceIdLikePrefMetricsServiceDid(
+ const std::string& original_device_id) {
+ if (original_device_id.empty())
+ return std::string();
+ return base::ToLowerASCII(
+ GetDigestString(original_device_id, "PrefMetricsService"));
+}
+
+} // namespace
+
+PrefHashCalculator::PrefHashCalculator(const std::string& seed,
+ const std::string& device_id)
+ : seed_(seed),
+ device_id_(device_id),
+ legacy_device_id_(GenerateDeviceIdLikePrefMetricsServiceDid(device_id)) {
+}
+
+PrefHashCalculator::~PrefHashCalculator() {
+}
+
+std::string PrefHashCalculator::Calculate(const std::string& path,
+ const base::Value* value) const {
+ return GetDigestString(seed_,
+ GetMessage(device_id_, path, ValueAsString(value)));
+}
+
+PrefHashCalculator::ValidationResult PrefHashCalculator::Validate(
+ const std::string& path,
+ const base::Value* value,
+ const std::string& digest_string) const {
+ const std::string value_as_string(ValueAsString(value));
+ if (VerifyDigestString(seed_, GetMessage(device_id_, path, value_as_string),
+ digest_string)) {
+ return VALID;
+ }
+ if (VerifyDigestString(seed_,
+ GetMessage(legacy_device_id_, path, value_as_string),
+ digest_string)) {
+ return VALID_SECURE_LEGACY;
+ }
+ return INVALID;
+}
diff --git a/chromium/components/user_prefs/tracked/pref_hash_calculator.h b/chromium/components/user_prefs/tracked/pref_hash_calculator.h
new file mode 100644
index 00000000000..593828ec213
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_calculator.h
@@ -0,0 +1,52 @@
+// 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_USER_PREFS_TRACKED_PREF_HASH_CALCULATOR_H_
+#define COMPONENTS_USER_PREFS_TRACKED_PREF_HASH_CALCULATOR_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+
+namespace base {
+class Value;
+} // namespace base
+
+// Calculates and validates preference value hashes.
+class PrefHashCalculator {
+ public:
+ enum ValidationResult {
+ INVALID,
+ VALID,
+ // Valid under a deprecated but as secure algorithm.
+ VALID_SECURE_LEGACY,
+ };
+
+ // Constructs a PrefHashCalculator using |seed| and |device_id|. The same
+ // parameters must be used in order to successfully validate generated hashes.
+ // |device_id| may be empty.
+ PrefHashCalculator(const std::string& seed, const std::string& device_id);
+
+ ~PrefHashCalculator();
+
+ // Calculates a hash value for the supplied preference |path| and |value|.
+ // |value| may be null if the preference has no value.
+ std::string Calculate(const std::string& path,
+ const base::Value* value) const;
+
+ // Validates the provided preference hash using current and legacy hashing
+ // algorithms.
+ ValidationResult Validate(const std::string& path,
+ const base::Value* value,
+ const std::string& hash) const;
+
+ private:
+ const std::string seed_;
+ const std::string device_id_;
+ const std::string legacy_device_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefHashCalculator);
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_PREF_HASH_CALCULATOR_H_
diff --git a/chromium/components/user_prefs/tracked/pref_hash_calculator_unittest.cc b/chromium/components/user_prefs/tracked/pref_hash_calculator_unittest.cc
new file mode 100644
index 00000000000..4fc1ff6f2b5
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_calculator_unittest.cc
@@ -0,0 +1,202 @@
+// 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/user_prefs/tracked/pref_hash_calculator.h"
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(PrefHashCalculatorTest, TestCurrentAlgorithm) {
+ base::StringValue string_value_1("string value 1");
+ base::StringValue string_value_2("string value 2");
+ base::DictionaryValue dictionary_value_1;
+ dictionary_value_1.SetInteger("int value", 1);
+ dictionary_value_1.Set("nested empty map", new base::DictionaryValue);
+ base::DictionaryValue dictionary_value_1_equivalent;
+ dictionary_value_1_equivalent.SetInteger("int value", 1);
+ base::DictionaryValue dictionary_value_2;
+ dictionary_value_2.SetInteger("int value", 2);
+
+ PrefHashCalculator calc1("seed1", "deviceid");
+ PrefHashCalculator calc1_dup("seed1", "deviceid");
+ PrefHashCalculator calc2("seed2", "deviceid");
+ PrefHashCalculator calc3("seed1", "deviceid2");
+
+ // Two calculators with same seed produce same hash.
+ ASSERT_EQ(calc1.Calculate("pref_path", &string_value_1),
+ calc1_dup.Calculate("pref_path", &string_value_1));
+ ASSERT_EQ(PrefHashCalculator::VALID,
+ calc1_dup.Validate("pref_path", &string_value_1,
+ calc1.Calculate("pref_path", &string_value_1)));
+
+ // Different seeds, different hashes.
+ ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
+ calc2.Calculate("pref_path", &string_value_1));
+ ASSERT_EQ(PrefHashCalculator::INVALID,
+ calc2.Validate("pref_path", &string_value_1,
+ calc1.Calculate("pref_path", &string_value_1)));
+
+ // Different device IDs, different hashes.
+ ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
+ calc3.Calculate("pref_path", &string_value_1));
+
+ // Different values, different hashes.
+ ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
+ calc1.Calculate("pref_path", &string_value_2));
+
+ // Different paths, different hashes.
+ ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
+ calc1.Calculate("pref_path_2", &string_value_1));
+
+ // Works for dictionaries.
+ ASSERT_EQ(calc1.Calculate("pref_path", &dictionary_value_1),
+ calc1.Calculate("pref_path", &dictionary_value_1));
+ ASSERT_NE(calc1.Calculate("pref_path", &dictionary_value_1),
+ calc1.Calculate("pref_path", &dictionary_value_2));
+
+ // Empty dictionary children are pruned.
+ ASSERT_EQ(calc1.Calculate("pref_path", &dictionary_value_1),
+ calc1.Calculate("pref_path", &dictionary_value_1_equivalent));
+
+ // NULL value is supported.
+ ASSERT_FALSE(calc1.Calculate("pref_path", NULL).empty());
+}
+
+// Tests the output against a known value to catch unexpected algorithm changes.
+// The test hashes below must NEVER be updated, the serialization algorithm used
+// must always be able to generate data that will produce these exact hashes.
+TEST(PrefHashCalculatorTest, CatchHashChanges) {
+ static const char kSeed[] = "0123456789ABCDEF0123456789ABCDEF";
+ static const char kDeviceId[] = "test_device_id1";
+
+ scoped_ptr<base::Value> null_value = base::Value::CreateNullValue();
+ scoped_ptr<base::Value> bool_value(new base::FundamentalValue(false));
+ scoped_ptr<base::Value> int_value(new base::FundamentalValue(1234567890));
+ scoped_ptr<base::Value> double_value(
+ new base::FundamentalValue(123.0987654321));
+ scoped_ptr<base::Value> string_value(
+ new base::StringValue("testing with special chars:\n<>{}:^^@#$\\/"));
+
+ // For legacy reasons, we have to support pruning of empty lists/dictionaries
+ // and nested empty ists/dicts in the hash generation algorithm.
+ scoped_ptr<base::DictionaryValue> nested_empty_dict(
+ new base::DictionaryValue);
+ nested_empty_dict->Set("a", new base::DictionaryValue);
+ nested_empty_dict->Set("b", new base::ListValue);
+ scoped_ptr<base::ListValue> nested_empty_list(new base::ListValue);
+ nested_empty_list->Append(new base::DictionaryValue);
+ nested_empty_list->Append(new base::ListValue);
+ nested_empty_list->Append(nested_empty_dict->DeepCopy());
+
+ // A dictionary with an empty dictionary, an empty list, and nested empty
+ // dictionaries/lists in it.
+ scoped_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue);
+ dict_value->Set("a", new base::StringValue("foo"));
+ dict_value->Set("d", new base::ListValue);
+ dict_value->Set("b", new base::DictionaryValue);
+ dict_value->Set("c", new base::StringValue("baz"));
+ dict_value->Set("e", nested_empty_dict.release());
+ dict_value->Set("f", nested_empty_list.release());
+
+ scoped_ptr<base::ListValue> list_value(new base::ListValue);
+ list_value->AppendBoolean(true);
+ list_value->AppendInteger(100);
+ list_value->AppendDouble(1.0);
+
+ ASSERT_EQ(base::Value::TYPE_NULL, null_value->GetType());
+ ASSERT_EQ(base::Value::TYPE_BOOLEAN, bool_value->GetType());
+ ASSERT_EQ(base::Value::TYPE_INTEGER, int_value->GetType());
+ ASSERT_EQ(base::Value::TYPE_DOUBLE, double_value->GetType());
+ ASSERT_EQ(base::Value::TYPE_STRING, string_value->GetType());
+ ASSERT_EQ(base::Value::TYPE_DICTIONARY, dict_value->GetType());
+ ASSERT_EQ(base::Value::TYPE_LIST, list_value->GetType());
+
+ // Test every value type independently. Intentionally omits TYPE_BINARY which
+ // isn't even allowed in JSONWriter's input.
+ static const char kExpectedNullValue[] =
+ "82A9F3BBC7F9FF84C76B033C854E79EEB162783FA7B3E99FF9372FA8E12C44F7";
+ EXPECT_EQ(PrefHashCalculator::VALID,
+ PrefHashCalculator(kSeed, kDeviceId)
+ .Validate("pref.path", null_value.get(), kExpectedNullValue));
+
+ static const char kExpectedBooleanValue[] =
+ "A520D8F43EA307B0063736DC9358C330539D0A29417580514C8B9862632C4CCC";
+ EXPECT_EQ(
+ PrefHashCalculator::VALID,
+ PrefHashCalculator(kSeed, kDeviceId)
+ .Validate("pref.path", bool_value.get(), kExpectedBooleanValue));
+
+ static const char kExpectedIntegerValue[] =
+ "8D60DA1F10BF5AA29819D2D66D7CCEF9AABC5DA93C11A0D2BD21078D63D83682";
+ EXPECT_EQ(PrefHashCalculator::VALID,
+ PrefHashCalculator(kSeed, kDeviceId)
+ .Validate("pref.path", int_value.get(), kExpectedIntegerValue));
+
+ static const char kExpectedDoubleValue[] =
+ "C9D94772516125BEEDAE68C109D44BC529E719EE020614E894CC7FB4098C545D";
+ EXPECT_EQ(
+ PrefHashCalculator::VALID,
+ PrefHashCalculator(kSeed, kDeviceId)
+ .Validate("pref.path", double_value.get(), kExpectedDoubleValue));
+
+ static const char kExpectedStringValue[] =
+ "05ACCBD3B05C45C36CD06190F63EC577112311929D8380E26E5F13182EB68318";
+ EXPECT_EQ(
+ PrefHashCalculator::VALID,
+ PrefHashCalculator(kSeed, kDeviceId)
+ .Validate("pref.path", string_value.get(), kExpectedStringValue));
+
+ static const char kExpectedDictValue[] =
+ "7A84DCC710D796C771F789A4DA82C952095AA956B6F1667EE42D0A19ECAA3C4A";
+ EXPECT_EQ(PrefHashCalculator::VALID,
+ PrefHashCalculator(kSeed, kDeviceId)
+ .Validate("pref.path", dict_value.get(), kExpectedDictValue));
+
+ static const char kExpectedListValue[] =
+ "8D5A25972DF5AE20D041C780E7CA54E40F614AD53513A0724EE8D62D4F992740";
+ EXPECT_EQ(PrefHashCalculator::VALID,
+ PrefHashCalculator(kSeed, kDeviceId)
+ .Validate("pref.path", list_value.get(), kExpectedListValue));
+
+ // Also test every value type together in the same dictionary.
+ base::DictionaryValue everything;
+ everything.Set("null", null_value.release());
+ everything.Set("bool", bool_value.release());
+ everything.Set("int", int_value.release());
+ everything.Set("double", double_value.release());
+ everything.Set("string", string_value.release());
+ everything.Set("list", list_value.release());
+ everything.Set("dict", dict_value.release());
+ static const char kExpectedEverythingValue[] =
+ "B97D09BE7005693574DCBDD03D8D9E44FB51F4008B73FB56A49A9FA671A1999B";
+ EXPECT_EQ(PrefHashCalculator::VALID,
+ PrefHashCalculator(kSeed, kDeviceId)
+ .Validate("pref.path", &everything, kExpectedEverythingValue));
+}
+
+TEST(PrefHashCalculatorTest, TestCompatibilityWithLegacyPrefMetricsServiceId) {
+ static const char kSeed[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+ static const char kDeviceId[] =
+ "D730D9CBD98C734A4FB097A1922275FE9F7E026A4EA1BE0E84";
+ static const char kExpectedValue[] =
+ "845EF34663FF8D32BE6707F40258FBA531C2BFC532E3B014AFB3476115C2A9DE";
+
+ base::ListValue startup_urls;
+ startup_urls.Set(0, new base::StringValue("http://www.chromium.org/"));
+
+ EXPECT_EQ(
+ PrefHashCalculator::VALID_SECURE_LEGACY,
+ PrefHashCalculator(std::string(kSeed, arraysize(kSeed)), kDeviceId)
+ .Validate("session.startup_urls", &startup_urls, kExpectedValue));
+}
diff --git a/chromium/components/user_prefs/tracked/pref_hash_filter.cc b/chromium/components/user_prefs/tracked/pref_hash_filter.cc
new file mode 100644
index 00000000000..d3cd61d714b
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_filter.cc
@@ -0,0 +1,230 @@
+// 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/user_prefs/tracked/pref_hash_filter.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "base/prefs/pref_service.h"
+#include "base/prefs/pref_store.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/user_prefs/tracked/dictionary_hash_store_contents.h"
+#include "components/user_prefs/tracked/pref_hash_store.h"
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+#include "components/user_prefs/tracked/pref_names.h"
+#include "components/user_prefs/tracked/tracked_atomic_preference.h"
+#include "components/user_prefs/tracked/tracked_split_preference.h"
+
+namespace {
+
+void CleanupDeprecatedTrackedPreferences(
+ base::DictionaryValue* pref_store_contents,
+ PrefHashStoreTransaction* hash_store_transaction) {
+ // Add deprecated previously tracked preferences below for them to be cleaned
+ // up from both the pref files and the hash store.
+ static const char* const kDeprecatedTrackedPreferences[] = {
+ // TODO(grt): Remove in M44+.
+ "safebrowsing.incident_report_sent",
+ // TODO(mad): Remove in M48+.
+ "software_reporter.prompt_reason",
+ };
+
+ for (size_t i = 0; i < arraysize(kDeprecatedTrackedPreferences); ++i) {
+ const char* key = kDeprecatedTrackedPreferences[i];
+ pref_store_contents->Remove(key, NULL);
+ hash_store_transaction->ClearHash(key);
+ }
+}
+
+} // namespace
+
+PrefHashFilter::PrefHashFilter(
+ scoped_ptr<PrefHashStore> pref_hash_store,
+ const std::vector<TrackedPreferenceMetadata>& tracked_preferences,
+ const base::Closure& on_reset_on_load,
+ TrackedPreferenceValidationDelegate* delegate,
+ size_t reporting_ids_count,
+ bool report_super_mac_validity)
+ : pref_hash_store_(pref_hash_store.Pass()),
+ on_reset_on_load_(on_reset_on_load),
+ report_super_mac_validity_(report_super_mac_validity) {
+ DCHECK(pref_hash_store_);
+ DCHECK_GE(reporting_ids_count, tracked_preferences.size());
+
+ for (size_t i = 0; i < tracked_preferences.size(); ++i) {
+ const TrackedPreferenceMetadata& metadata = tracked_preferences[i];
+
+ scoped_ptr<TrackedPreference> tracked_preference;
+ switch (metadata.strategy) {
+ case TRACKING_STRATEGY_ATOMIC:
+ tracked_preference.reset(
+ new TrackedAtomicPreference(metadata.name,
+ metadata.reporting_id,
+ reporting_ids_count,
+ metadata.enforcement_level,
+ metadata.value_type,
+ delegate));
+ break;
+ case TRACKING_STRATEGY_SPLIT:
+ tracked_preference.reset(
+ new TrackedSplitPreference(metadata.name,
+ metadata.reporting_id,
+ reporting_ids_count,
+ metadata.enforcement_level,
+ metadata.value_type,
+ delegate));
+ break;
+ }
+ DCHECK(tracked_preference);
+
+ bool is_new = tracked_paths_.add(metadata.name,
+ tracked_preference.Pass()).second;
+ DCHECK(is_new);
+ }
+}
+
+PrefHashFilter::~PrefHashFilter() {
+ // Ensure new values for all |changed_paths_| have been flushed to
+ // |pref_hash_store_| already.
+ DCHECK(changed_paths_.empty());
+}
+
+// static
+void PrefHashFilter::RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ // See GetResetTime for why this is a StringPref and not Int64Pref.
+ registry->RegisterStringPref(
+ user_prefs::kPreferenceResetTime,
+ base::Int64ToString(base::Time().ToInternalValue()));
+}
+
+// static
+base::Time PrefHashFilter::GetResetTime(PrefService* user_prefs) {
+ // Provide our own implementation (identical to the PrefService::GetInt64) in
+ // order to ensure it remains consistent with the way we store this value
+ // (which we do via a PrefStore, preventing us from reusing
+ // PrefService::SetInt64).
+ int64 internal_value = base::Time().ToInternalValue();
+ if (!base::StringToInt64(
+ user_prefs->GetString(user_prefs::kPreferenceResetTime),
+ &internal_value)) {
+ // Somehow the value stored on disk is not a valid int64.
+ NOTREACHED();
+ return base::Time();
+ }
+ return base::Time::FromInternalValue(internal_value);
+}
+
+// static
+void PrefHashFilter::ClearResetTime(PrefService* user_prefs) {
+ user_prefs->ClearPref(user_prefs::kPreferenceResetTime);
+}
+
+void PrefHashFilter::Initialize(base::DictionaryValue* pref_store_contents) {
+ scoped_ptr<PrefHashStoreTransaction> hash_store_transaction(
+ pref_hash_store_->BeginTransaction(scoped_ptr<HashStoreContents>(
+ new DictionaryHashStoreContents(pref_store_contents))));
+ for (TrackedPreferencesMap::const_iterator it = tracked_paths_.begin();
+ it != tracked_paths_.end(); ++it) {
+ const std::string& initialized_path = it->first;
+ const TrackedPreference* initialized_preference = it->second;
+ const base::Value* value = NULL;
+ pref_store_contents->Get(initialized_path, &value);
+ initialized_preference->OnNewValue(value, hash_store_transaction.get());
+ }
+}
+
+// Marks |path| has having changed if it is part of |tracked_paths_|. A new hash
+// will be stored for it the next time FilterSerializeData() is invoked.
+void PrefHashFilter::FilterUpdate(const std::string& path) {
+ TrackedPreferencesMap::const_iterator it = tracked_paths_.find(path);
+ if (it != tracked_paths_.end())
+ changed_paths_.insert(std::make_pair(path, it->second));
+}
+
+// Updates the stored hashes for |changed_paths_| before serializing data to
+// disk. This is required as storing the hash everytime a pref's value changes
+// is too expensive (see perf regression @ http://crbug.com/331273).
+void PrefHashFilter::FilterSerializeData(
+ base::DictionaryValue* pref_store_contents) {
+ if (!changed_paths_.empty()) {
+ base::TimeTicks checkpoint = base::TimeTicks::Now();
+ {
+ scoped_ptr<PrefHashStoreTransaction> hash_store_transaction(
+ pref_hash_store_->BeginTransaction(scoped_ptr<HashStoreContents>(
+ new DictionaryHashStoreContents(pref_store_contents))));
+ for (ChangedPathsMap::const_iterator it = changed_paths_.begin();
+ it != changed_paths_.end(); ++it) {
+ const std::string& changed_path = it->first;
+ const TrackedPreference* changed_preference = it->second;
+ const base::Value* value = NULL;
+ pref_store_contents->Get(changed_path, &value);
+ changed_preference->OnNewValue(value, hash_store_transaction.get());
+ }
+ changed_paths_.clear();
+ }
+ // TODO(gab): Remove this histogram by Feb 21 2014; after sufficient timing
+ // data has been gathered from the wild to be confident this doesn't
+ // significantly affect performance on the UI thread.
+ UMA_HISTOGRAM_TIMES("Settings.FilterSerializeDataTime",
+ base::TimeTicks::Now() - checkpoint);
+ }
+}
+
+void PrefHashFilter::FinalizeFilterOnLoad(
+ const PostFilterOnLoadCallback& post_filter_on_load_callback,
+ scoped_ptr<base::DictionaryValue> pref_store_contents,
+ bool prefs_altered) {
+ DCHECK(pref_store_contents);
+ base::TimeTicks checkpoint = base::TimeTicks::Now();
+
+ bool did_reset = false;
+ {
+ scoped_ptr<PrefHashStoreTransaction> hash_store_transaction(
+ pref_hash_store_->BeginTransaction(scoped_ptr<HashStoreContents>(
+ new DictionaryHashStoreContents(pref_store_contents.get()))));
+
+ CleanupDeprecatedTrackedPreferences(
+ pref_store_contents.get(), hash_store_transaction.get());
+
+ if (report_super_mac_validity_) {
+ UMA_HISTOGRAM_BOOLEAN("Settings.HashesDictionaryTrusted",
+ hash_store_transaction->IsSuperMACValid());
+ }
+
+ for (TrackedPreferencesMap::const_iterator it = tracked_paths_.begin();
+ it != tracked_paths_.end(); ++it) {
+ if (it->second->EnforceAndReport(pref_store_contents.get(),
+ hash_store_transaction.get())) {
+ did_reset = true;
+ prefs_altered = true;
+ }
+ }
+ if (hash_store_transaction->StampSuperMac())
+ prefs_altered = true;
+ }
+
+ if (did_reset) {
+ pref_store_contents->Set(user_prefs::kPreferenceResetTime,
+ new base::StringValue(base::Int64ToString(
+ base::Time::Now().ToInternalValue())));
+ FilterUpdate(user_prefs::kPreferenceResetTime);
+
+ if (!on_reset_on_load_.is_null())
+ on_reset_on_load_.Run();
+ }
+
+ // TODO(gab): Remove this histogram by Feb 21 2014; after sufficient timing
+ // data has been gathered from the wild to be confident this doesn't
+ // significantly affect startup.
+ UMA_HISTOGRAM_TIMES("Settings.FilterOnLoadTime",
+ base::TimeTicks::Now() - checkpoint);
+
+ post_filter_on_load_callback.Run(pref_store_contents.Pass(), prefs_altered);
+}
diff --git a/chromium/components/user_prefs/tracked/pref_hash_filter.h b/chromium/components/user_prefs/tracked/pref_hash_filter.h
new file mode 100644
index 00000000000..54995694063
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_filter.h
@@ -0,0 +1,141 @@
+// 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_USER_PREFS_TRACKED_PREF_HASH_FILTER_H_
+#define COMPONENTS_USER_PREFS_TRACKED_PREF_HASH_FILTER_H_
+
+#include <map>
+#include <set>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/user_prefs/tracked/interceptable_pref_filter.h"
+#include "components/user_prefs/tracked/tracked_preference.h"
+
+class PrefHashStore;
+class PrefService;
+class PrefStore;
+class TrackedPreferenceValidationDelegate;
+
+namespace base {
+class DictionaryValue;
+class Time;
+class Value;
+} // namespace base
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+} // namespace user_prefs
+
+// Intercepts preference values as they are loaded from disk and verifies them
+// using a PrefHashStore. Keeps the PrefHashStore contents up to date as values
+// are changed.
+class PrefHashFilter : public InterceptablePrefFilter {
+ public:
+ enum EnforcementLevel { NO_ENFORCEMENT, ENFORCE_ON_LOAD };
+
+ enum PrefTrackingStrategy {
+ // Atomic preferences are tracked as a whole.
+ TRACKING_STRATEGY_ATOMIC,
+ // Split preferences are dictionaries for which each top-level entry is
+ // tracked independently. Note: preferences using this strategy must be kept
+ // in sync with TrackedSplitPreferences in histograms.xml.
+ TRACKING_STRATEGY_SPLIT,
+ };
+
+ enum ValueType {
+ VALUE_IMPERSONAL,
+ // The preference value may contain personal information.
+ VALUE_PERSONAL,
+ };
+
+ struct TrackedPreferenceMetadata {
+ size_t reporting_id;
+ const char* name;
+ EnforcementLevel enforcement_level;
+ PrefTrackingStrategy strategy;
+ ValueType value_type;
+ };
+
+ // Constructs a PrefHashFilter tracking the specified |tracked_preferences|
+ // using |pref_hash_store| to check/store hashes. An optional |delegate| is
+ // notified of the status of each preference as it is checked.
+ // If |on_reset_on_load| is provided, it will be invoked if a reset occurs in
+ // FilterOnLoad.
+ // |reporting_ids_count| is the count of all possible IDs (possibly greater
+ // than |tracked_preferences.size()|). If |report_super_mac_validity| is true,
+ // the state of the super MAC will be reported via UMA during
+ // FinalizeFilterOnLoad.
+ PrefHashFilter(
+ scoped_ptr<PrefHashStore> pref_hash_store,
+ const std::vector<TrackedPreferenceMetadata>& tracked_preferences,
+ const base::Closure& on_reset_on_load,
+ TrackedPreferenceValidationDelegate* delegate,
+ size_t reporting_ids_count,
+ bool report_super_mac_validity);
+
+ ~PrefHashFilter() override;
+
+ // Registers required user preferences.
+ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+ // Retrieves the time of the last reset event, if any, for the provided user
+ // preferences. If no reset has occurred, Returns a null |Time|.
+ static base::Time GetResetTime(PrefService* user_prefs);
+
+ // Clears the time of the last reset event, if any, for the provided user
+ // preferences.
+ static void ClearResetTime(PrefService* user_prefs);
+
+ // Initializes the PrefHashStore with hashes of the tracked preferences in
+ // |pref_store_contents|. |pref_store_contents| will be the |storage| passed
+ // to PrefHashStore::BeginTransaction().
+ void Initialize(base::DictionaryValue* pref_store_contents);
+
+ // PrefFilter remaining implementation.
+ void FilterUpdate(const std::string& path) override;
+ void FilterSerializeData(base::DictionaryValue* pref_store_contents) override;
+
+ private:
+ // InterceptablePrefFilter implementation.
+ void FinalizeFilterOnLoad(
+ const PostFilterOnLoadCallback& post_filter_on_load_callback,
+ scoped_ptr<base::DictionaryValue> pref_store_contents,
+ bool prefs_altered) override;
+
+ // Callback to be invoked only once (and subsequently reset) on the next
+ // FilterOnLoad event. It will be allowed to modify the |prefs| handed to
+ // FilterOnLoad before handing them back to this PrefHashFilter.
+ FilterOnLoadInterceptor filter_on_load_interceptor_;
+
+ // A map of paths to TrackedPreferences; this map owns this individual
+ // TrackedPreference objects.
+ typedef base::ScopedPtrHashMap<std::string, scoped_ptr<TrackedPreference>>
+ TrackedPreferencesMap;
+ // A map from changed paths to their corresponding TrackedPreferences (which
+ // aren't owned by this map).
+ typedef std::map<std::string, const TrackedPreference*> ChangedPathsMap;
+
+ scoped_ptr<PrefHashStore> pref_hash_store_;
+
+ // Invoked if a reset occurs in a call to FilterOnLoad.
+ const base::Closure on_reset_on_load_;
+
+ TrackedPreferencesMap tracked_paths_;
+
+ // The set of all paths whose value has changed since the last call to
+ // FilterSerializeData.
+ ChangedPathsMap changed_paths_;
+
+ // Whether to report the validity of the super MAC at load time (via UMA).
+ bool report_super_mac_validity_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefHashFilter);
+};
+
+#endif // COMPONENTS_PREFS_TRACKED_PREF_HASH_FILTER_H_
diff --git a/chromium/components/user_prefs/tracked/pref_hash_filter_unittest.cc b/chromium/components/user_prefs/tracked/pref_hash_filter_unittest.cc
new file mode 100644
index 00000000000..2d1f4d34c31
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_filter_unittest.cc
@@ -0,0 +1,1039 @@
+// 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/user_prefs/tracked/pref_hash_filter.h"
+
+#include <map>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/callback_forward.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram_base.h"
+#include "base/metrics/histogram_samples.h"
+#include "base/metrics/statistics_recorder.h"
+#include "base/prefs/testing_pref_store.h"
+#include "base/values.h"
+#include "components/user_prefs/tracked/hash_store_contents.h"
+#include "components/user_prefs/tracked/mock_validation_delegate.h"
+#include "components/user_prefs/tracked/pref_hash_store.h"
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+#include "components/user_prefs/tracked/pref_names.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char kAtomicPref[] = "atomic_pref";
+const char kAtomicPref2[] = "atomic_pref2";
+const char kAtomicPref3[] = "pref3";
+const char kAtomicPref4[] = "pref4";
+const char kReportOnlyPref[] = "report_only";
+const char kReportOnlySplitPref[] = "report_only_split_pref";
+const char kSplitPref[] = "split_pref";
+
+const PrefHashFilter::TrackedPreferenceMetadata kTestTrackedPrefs[] = {
+ {0,
+ kAtomicPref,
+ PrefHashFilter::ENFORCE_ON_LOAD,
+ PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ PrefHashFilter::VALUE_PERSONAL},
+ {1,
+ kReportOnlyPref,
+ PrefHashFilter::NO_ENFORCEMENT,
+ PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ PrefHashFilter::VALUE_IMPERSONAL},
+ {2,
+ kSplitPref,
+ PrefHashFilter::ENFORCE_ON_LOAD,
+ PrefHashFilter::TRACKING_STRATEGY_SPLIT,
+ PrefHashFilter::VALUE_IMPERSONAL},
+ {3,
+ kReportOnlySplitPref,
+ PrefHashFilter::NO_ENFORCEMENT,
+ PrefHashFilter::TRACKING_STRATEGY_SPLIT,
+ PrefHashFilter::VALUE_IMPERSONAL},
+ {4,
+ kAtomicPref2,
+ PrefHashFilter::ENFORCE_ON_LOAD,
+ PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ PrefHashFilter::VALUE_IMPERSONAL},
+ {5,
+ kAtomicPref3,
+ PrefHashFilter::ENFORCE_ON_LOAD,
+ PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ PrefHashFilter::VALUE_IMPERSONAL},
+ {6,
+ kAtomicPref4,
+ PrefHashFilter::ENFORCE_ON_LOAD,
+ PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ PrefHashFilter::VALUE_IMPERSONAL},
+};
+
+} // namespace
+
+// A PrefHashStore that allows simulation of CheckValue results and captures
+// checked and stored values.
+class MockPrefHashStore : public PrefHashStore {
+ public:
+ typedef std::pair<const void*, PrefHashFilter::PrefTrackingStrategy>
+ ValuePtrStrategyPair;
+
+ MockPrefHashStore()
+ : stamp_super_mac_result_(false),
+ is_super_mac_valid_result_(false),
+ transactions_performed_(0),
+ transaction_active_(false) {}
+
+ ~MockPrefHashStore() override { EXPECT_FALSE(transaction_active_); }
+
+ // Set the result that will be returned when |path| is passed to
+ // |CheckValue/CheckSplitValue|.
+ void SetCheckResult(const std::string& path,
+ PrefHashStoreTransaction::ValueState result);
+
+ // Set the invalid_keys that will be returned when |path| is passed to
+ // |CheckSplitValue|. SetCheckResult should already have been called for
+ // |path| with |result == CHANGED| for this to make any sense.
+ void SetInvalidKeysResult(
+ const std::string& path,
+ const std::vector<std::string>& invalid_keys_result);
+
+ // Sets the value that will be returned from
+ // PrefHashStoreTransaction::StampSuperMAC().
+ void set_stamp_super_mac_result(bool result) {
+ stamp_super_mac_result_ = result;
+ }
+
+ // Sets the value that will be returned from
+ // PrefHashStoreTransaction::IsSuperMACValid().
+ void set_is_super_mac_valid_result(bool result) {
+ is_super_mac_valid_result_ = result;
+ }
+
+ // Returns the number of transactions that were performed.
+ size_t transactions_performed() { return transactions_performed_; }
+
+ // Returns the number of paths checked.
+ size_t checked_paths_count() const { return checked_values_.size(); }
+
+ // Returns the number of paths stored.
+ size_t stored_paths_count() const { return stored_values_.size(); }
+
+ // Returns the pointer value and strategy that was passed to
+ // |CheckHash/CheckSplitHash| for |path|. The returned pointer could since
+ // have been freed and is thus not safe to dereference.
+ ValuePtrStrategyPair checked_value(const std::string& path) const {
+ std::map<std::string, ValuePtrStrategyPair>::const_iterator value =
+ checked_values_.find(path);
+ if (value != checked_values_.end())
+ return value->second;
+ return std::make_pair(
+ reinterpret_cast<void*>(0xBAD),
+ static_cast<PrefHashFilter::PrefTrackingStrategy>(-1));
+ }
+
+ // Returns the pointer value that was passed to |StoreHash/StoreSplitHash| for
+ // |path|. The returned pointer could since have been freed and is thus not
+ // safe to dereference.
+ ValuePtrStrategyPair stored_value(const std::string& path) const {
+ std::map<std::string, ValuePtrStrategyPair>::const_iterator value =
+ stored_values_.find(path);
+ if (value != stored_values_.end())
+ return value->second;
+ return std::make_pair(
+ reinterpret_cast<void*>(0xBAD),
+ static_cast<PrefHashFilter::PrefTrackingStrategy>(-1));
+ }
+
+ // PrefHashStore implementation.
+ scoped_ptr<PrefHashStoreTransaction> BeginTransaction(
+ scoped_ptr<HashStoreContents> storage) override;
+
+ private:
+ // A MockPrefHashStoreTransaction is handed to the caller on
+ // MockPrefHashStore::BeginTransaction(). It then stores state in its
+ // underlying MockPrefHashStore about calls it receives from that same caller
+ // which can later be verified in tests.
+ class MockPrefHashStoreTransaction : public PrefHashStoreTransaction {
+ public:
+ explicit MockPrefHashStoreTransaction(MockPrefHashStore* outer)
+ : outer_(outer) {}
+
+ ~MockPrefHashStoreTransaction() override {
+ outer_->transaction_active_ = false;
+ ++outer_->transactions_performed_;
+ }
+
+ // PrefHashStoreTransaction implementation.
+ PrefHashStoreTransaction::ValueState CheckValue(
+ const std::string& path,
+ const base::Value* value) const override;
+ void StoreHash(const std::string& path,
+ const base::Value* new_value) override;
+ PrefHashStoreTransaction::ValueState CheckSplitValue(
+ const std::string& path,
+ const base::DictionaryValue* initial_split_value,
+ std::vector<std::string>* invalid_keys) const override;
+ void StoreSplitHash(const std::string& path,
+ const base::DictionaryValue* split_value) override;
+ bool HasHash(const std::string& path) const override;
+ void ImportHash(const std::string& path, const base::Value* hash) override;
+ void ClearHash(const std::string& path) override;
+ bool IsSuperMACValid() const override;
+ bool StampSuperMac() override;
+
+ private:
+ MockPrefHashStore* outer_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockPrefHashStoreTransaction);
+ };
+
+ // Records a call to this mock's CheckValue/CheckSplitValue methods.
+ PrefHashStoreTransaction::ValueState RecordCheckValue(
+ const std::string& path,
+ const base::Value* value,
+ PrefHashFilter::PrefTrackingStrategy strategy);
+
+ // Records a call to this mock's StoreHash/StoreSplitHash methods.
+ void RecordStoreHash(const std::string& path,
+ const base::Value* new_value,
+ PrefHashFilter::PrefTrackingStrategy strategy);
+
+ std::map<std::string, PrefHashStoreTransaction::ValueState> check_results_;
+ std::map<std::string, std::vector<std::string>> invalid_keys_results_;
+
+ bool stamp_super_mac_result_;
+ bool is_super_mac_valid_result_;
+
+ std::map<std::string, ValuePtrStrategyPair> checked_values_;
+ std::map<std::string, ValuePtrStrategyPair> stored_values_;
+
+ // Number of transactions that were performed via this MockPrefHashStore.
+ size_t transactions_performed_;
+
+ // Whether a transaction is currently active (only one transaction should be
+ // active at a time).
+ bool transaction_active_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockPrefHashStore);
+};
+
+void MockPrefHashStore::SetCheckResult(
+ const std::string& path,
+ PrefHashStoreTransaction::ValueState result) {
+ check_results_.insert(std::make_pair(path, result));
+}
+
+void MockPrefHashStore::SetInvalidKeysResult(
+ const std::string& path,
+ const std::vector<std::string>& invalid_keys_result) {
+ // Ensure |check_results_| has a CHANGED entry for |path|.
+ std::map<std::string, PrefHashStoreTransaction::ValueState>::const_iterator
+ result = check_results_.find(path);
+ ASSERT_TRUE(result != check_results_.end());
+ ASSERT_EQ(PrefHashStoreTransaction::CHANGED, result->second);
+
+ invalid_keys_results_.insert(std::make_pair(path, invalid_keys_result));
+}
+
+scoped_ptr<PrefHashStoreTransaction> MockPrefHashStore::BeginTransaction(
+ scoped_ptr<HashStoreContents> storage) {
+ EXPECT_FALSE(transaction_active_);
+ return scoped_ptr<PrefHashStoreTransaction>(
+ new MockPrefHashStoreTransaction(this));
+}
+
+PrefHashStoreTransaction::ValueState MockPrefHashStore::RecordCheckValue(
+ const std::string& path,
+ const base::Value* value,
+ PrefHashFilter::PrefTrackingStrategy strategy) {
+ // Record that |path| was checked and validate that it wasn't previously
+ // checked.
+ EXPECT_TRUE(checked_values_.insert(std::make_pair(
+ path, std::make_pair(value, strategy)))
+ .second);
+ std::map<std::string, PrefHashStoreTransaction::ValueState>::const_iterator
+ result = check_results_.find(path);
+ if (result != check_results_.end())
+ return result->second;
+ return PrefHashStoreTransaction::UNCHANGED;
+}
+
+void MockPrefHashStore::RecordStoreHash(
+ const std::string& path,
+ const base::Value* new_value,
+ PrefHashFilter::PrefTrackingStrategy strategy) {
+ EXPECT_TRUE(
+ stored_values_.insert(std::make_pair(path,
+ std::make_pair(new_value, strategy)))
+ .second);
+}
+
+PrefHashStoreTransaction::ValueState
+MockPrefHashStore::MockPrefHashStoreTransaction::CheckValue(
+ const std::string& path,
+ const base::Value* value) const {
+ return outer_->RecordCheckValue(path, value,
+ PrefHashFilter::TRACKING_STRATEGY_ATOMIC);
+}
+
+void MockPrefHashStore::MockPrefHashStoreTransaction::StoreHash(
+ const std::string& path,
+ const base::Value* new_value) {
+ outer_->RecordStoreHash(path, new_value,
+ PrefHashFilter::TRACKING_STRATEGY_ATOMIC);
+}
+
+PrefHashStoreTransaction::ValueState
+MockPrefHashStore::MockPrefHashStoreTransaction::CheckSplitValue(
+ const std::string& path,
+ const base::DictionaryValue* initial_split_value,
+ std::vector<std::string>* invalid_keys) const {
+ EXPECT_TRUE(invalid_keys && invalid_keys->empty());
+
+ std::map<std::string, std::vector<std::string>>::const_iterator
+ invalid_keys_result = outer_->invalid_keys_results_.find(path);
+ if (invalid_keys_result != outer_->invalid_keys_results_.end()) {
+ invalid_keys->insert(invalid_keys->begin(),
+ invalid_keys_result->second.begin(),
+ invalid_keys_result->second.end());
+ }
+
+ return outer_->RecordCheckValue(path, initial_split_value,
+ PrefHashFilter::TRACKING_STRATEGY_SPLIT);
+}
+
+void MockPrefHashStore::MockPrefHashStoreTransaction::StoreSplitHash(
+ const std::string& path,
+ const base::DictionaryValue* new_value) {
+ outer_->RecordStoreHash(path, new_value,
+ PrefHashFilter::TRACKING_STRATEGY_SPLIT);
+}
+
+bool MockPrefHashStore::MockPrefHashStoreTransaction::HasHash(
+ const std::string& path) const {
+ ADD_FAILURE() << "Unexpected call.";
+ return false;
+}
+
+void MockPrefHashStore::MockPrefHashStoreTransaction::ImportHash(
+ const std::string& path,
+ const base::Value* hash) {
+ ADD_FAILURE() << "Unexpected call.";
+}
+
+void MockPrefHashStore::MockPrefHashStoreTransaction::ClearHash(
+ const std::string& path) {
+ // Allow this to be called by PrefHashFilter's deprecated tracked prefs
+ // cleanup tasks.
+}
+
+bool MockPrefHashStore::MockPrefHashStoreTransaction::IsSuperMACValid() const {
+ return outer_->is_super_mac_valid_result_;
+}
+
+bool MockPrefHashStore::MockPrefHashStoreTransaction::StampSuperMac() {
+ return outer_->stamp_super_mac_result_;
+}
+
+std::vector<PrefHashFilter::TrackedPreferenceMetadata> GetConfiguration(
+ PrefHashFilter::EnforcementLevel max_enforcement_level) {
+ std::vector<PrefHashFilter::TrackedPreferenceMetadata> configuration(
+ kTestTrackedPrefs, kTestTrackedPrefs + arraysize(kTestTrackedPrefs));
+ for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::iterator it =
+ configuration.begin();
+ it != configuration.end(); ++it) {
+ if (it->enforcement_level > max_enforcement_level)
+ it->enforcement_level = max_enforcement_level;
+ }
+ return configuration;
+}
+
+class PrefHashFilterTest
+ : public testing::TestWithParam<PrefHashFilter::EnforcementLevel> {
+ public:
+ PrefHashFilterTest()
+ : mock_pref_hash_store_(NULL),
+ pref_store_contents_(new base::DictionaryValue),
+ reset_recorded_(false) {}
+
+ void SetUp() override {
+ base::StatisticsRecorder::Initialize();
+ Reset();
+ }
+
+ protected:
+ // Reset the PrefHashFilter instance.
+ void Reset() {
+ // Construct a PrefHashFilter and MockPrefHashStore for the test.
+ InitializePrefHashFilter(GetConfiguration(GetParam()));
+ }
+
+ // Initializes |pref_hash_filter_| with a PrefHashFilter that uses a
+ // MockPrefHashStore. The raw pointer to the MockPrefHashStore (owned by the
+ // PrefHashFilter) is stored in |mock_pref_hash_store_|.
+ void InitializePrefHashFilter(const std::vector<
+ PrefHashFilter::TrackedPreferenceMetadata>& configuration) {
+ scoped_ptr<MockPrefHashStore> temp_mock_pref_hash_store(
+ new MockPrefHashStore);
+ mock_pref_hash_store_ = temp_mock_pref_hash_store.get();
+ pref_hash_filter_.reset(new PrefHashFilter(
+ temp_mock_pref_hash_store.Pass(), configuration,
+ base::Bind(&PrefHashFilterTest::RecordReset, base::Unretained(this)),
+ &mock_validation_delegate_, arraysize(kTestTrackedPrefs), true));
+ }
+
+ // Verifies whether a reset was reported by the PrefHashFiler. Also verifies
+ // that kPreferenceResetTime was set (or not) accordingly.
+ void VerifyRecordedReset(bool reset_expected) {
+ EXPECT_EQ(reset_expected, reset_recorded_);
+ EXPECT_EQ(reset_expected,
+ pref_store_contents_->Get(
+ user_prefs::kPreferenceResetTime, NULL));
+ }
+
+ // Calls FilterOnLoad() on |pref_hash_Filter_|. |pref_store_contents_| is
+ // handed off, but should be given back to us synchronously through
+ // GetPrefsBack() as there is no FilterOnLoadInterceptor installed on
+ // |pref_hash_filter_|.
+ void DoFilterOnLoad(bool expect_prefs_modifications) {
+ pref_hash_filter_->FilterOnLoad(
+ base::Bind(&PrefHashFilterTest::GetPrefsBack, base::Unretained(this),
+ expect_prefs_modifications),
+ pref_store_contents_.Pass());
+ }
+
+ MockPrefHashStore* mock_pref_hash_store_;
+ scoped_ptr<base::DictionaryValue> pref_store_contents_;
+ MockValidationDelegate mock_validation_delegate_;
+ scoped_ptr<PrefHashFilter> pref_hash_filter_;
+
+ private:
+ // Stores |prefs| back in |pref_store_contents| and ensure
+ // |expected_schedule_write| matches the reported |schedule_write|.
+ void GetPrefsBack(bool expected_schedule_write,
+ scoped_ptr<base::DictionaryValue> prefs,
+ bool schedule_write) {
+ pref_store_contents_ = prefs.Pass();
+ EXPECT_TRUE(pref_store_contents_);
+ EXPECT_EQ(expected_schedule_write, schedule_write);
+ }
+
+ void RecordReset() {
+ // As-is |reset_recorded_| is only designed to remember a single reset, make
+ // sure none was previously recorded.
+ EXPECT_FALSE(reset_recorded_);
+ reset_recorded_ = true;
+ }
+
+ bool reset_recorded_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefHashFilterTest);
+};
+
+TEST_P(PrefHashFilterTest, EmptyAndUnchanged) {
+ DoFilterOnLoad(false);
+ // All paths checked.
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_pref_hash_store_->checked_paths_count());
+ // No paths stored, since they all return |UNCHANGED|.
+ ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
+ // Since there was nothing in |pref_store_contents_| the checked value should
+ // have been NULL for all tracked preferences.
+ for (size_t i = 0; i < arraysize(kTestTrackedPrefs); ++i) {
+ ASSERT_EQ(
+ NULL,
+ mock_pref_hash_store_->checked_value(kTestTrackedPrefs[i].name).first);
+ }
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+ VerifyRecordedReset(false);
+
+ // Delegate saw all paths, and all unchanged.
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_validation_delegate_.recorded_validations_count());
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::UNCHANGED));
+}
+
+TEST_P(PrefHashFilterTest, StampSuperMACAltersStore) {
+ mock_pref_hash_store_->set_stamp_super_mac_result(true);
+ DoFilterOnLoad(true);
+ // No paths stored, since they all return |UNCHANGED|. The StampSuperMAC
+ // result is the only reason the prefs were considered altered.
+ ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
+}
+
+TEST_P(PrefHashFilterTest, FilterTrackedPrefUpdate) {
+ base::DictionaryValue root_dict;
+ // Ownership of |string_value| is transfered to |root_dict|.
+ base::Value* string_value = new base::StringValue("string value");
+ root_dict.Set(kAtomicPref, string_value);
+
+ // No path should be stored on FilterUpdate.
+ pref_hash_filter_->FilterUpdate(kAtomicPref);
+ ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
+
+ // One path should be stored on FilterSerializeData.
+ pref_hash_filter_->FilterSerializeData(&root_dict);
+ ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count());
+ MockPrefHashStore::ValuePtrStrategyPair stored_value =
+ mock_pref_hash_store_->stored_value(kAtomicPref);
+ ASSERT_EQ(string_value, stored_value.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC, stored_value.second);
+
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+ VerifyRecordedReset(false);
+}
+
+TEST_P(PrefHashFilterTest, ReportSuperMacValidity) {
+ // Do this once just to force the histogram to be defined.
+ DoFilterOnLoad(false);
+
+ base::HistogramBase* histogram = base::StatisticsRecorder::FindHistogram(
+ "Settings.HashesDictionaryTrusted");
+ ASSERT_TRUE(histogram);
+
+ base::HistogramBase::Count initial_untrusted =
+ histogram->SnapshotSamples()->GetCount(0);
+ base::HistogramBase::Count initial_trusted =
+ histogram->SnapshotSamples()->GetCount(1);
+
+ Reset();
+
+ // Run with an invalid super MAC.
+ mock_pref_hash_store_->set_is_super_mac_valid_result(false);
+
+ DoFilterOnLoad(false);
+
+ // Verify that the invalidity was reported.
+ ASSERT_EQ(initial_untrusted + 1, histogram->SnapshotSamples()->GetCount(0));
+ ASSERT_EQ(initial_trusted, histogram->SnapshotSamples()->GetCount(1));
+
+ Reset();
+
+ // Run with a valid super MAC.
+ mock_pref_hash_store_->set_is_super_mac_valid_result(true);
+
+ DoFilterOnLoad(false);
+
+ // Verify that the validity was reported.
+ ASSERT_EQ(initial_untrusted + 1, histogram->SnapshotSamples()->GetCount(0));
+ ASSERT_EQ(initial_trusted + 1, histogram->SnapshotSamples()->GetCount(1));
+}
+
+TEST_P(PrefHashFilterTest, FilterSplitPrefUpdate) {
+ base::DictionaryValue root_dict;
+ // Ownership of |dict_value| is transfered to |root_dict|.
+ base::DictionaryValue* dict_value = new base::DictionaryValue;
+ dict_value->SetString("a", "foo");
+ dict_value->SetInteger("b", 1234);
+ root_dict.Set(kSplitPref, dict_value);
+
+ // No path should be stored on FilterUpdate.
+ pref_hash_filter_->FilterUpdate(kSplitPref);
+ ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
+
+ // One path should be stored on FilterSerializeData.
+ pref_hash_filter_->FilterSerializeData(&root_dict);
+ ASSERT_EQ(1u, mock_pref_hash_store_->stored_paths_count());
+ MockPrefHashStore::ValuePtrStrategyPair stored_value =
+ mock_pref_hash_store_->stored_value(kSplitPref);
+ ASSERT_EQ(dict_value, stored_value.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_value.second);
+
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+ VerifyRecordedReset(false);
+}
+
+TEST_P(PrefHashFilterTest, FilterUntrackedPrefUpdate) {
+ base::DictionaryValue root_dict;
+ root_dict.Set("untracked", new base::StringValue("some value"));
+ pref_hash_filter_->FilterUpdate("untracked");
+
+ // No paths should be stored on FilterUpdate.
+ ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
+
+ // Nor on FilterSerializeData.
+ pref_hash_filter_->FilterSerializeData(&root_dict);
+ ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
+
+ // No transaction should even be started on FilterSerializeData() if there are
+ // no updates to perform.
+ ASSERT_EQ(0u, mock_pref_hash_store_->transactions_performed());
+}
+
+TEST_P(PrefHashFilterTest, MultiplePrefsFilterSerializeData) {
+ base::DictionaryValue root_dict;
+ // Ownership of the following values is transfered to |root_dict|.
+ base::Value* int_value1 = new base::FundamentalValue(1);
+ base::Value* int_value2 = new base::FundamentalValue(2);
+ base::Value* int_value3 = new base::FundamentalValue(3);
+ base::Value* int_value4 = new base::FundamentalValue(4);
+ base::DictionaryValue* dict_value = new base::DictionaryValue;
+ dict_value->Set("a", new base::FundamentalValue(true));
+ root_dict.Set(kAtomicPref, int_value1);
+ root_dict.Set(kAtomicPref2, int_value2);
+ root_dict.Set(kAtomicPref3, int_value3);
+ root_dict.Set("untracked", int_value4);
+ root_dict.Set(kSplitPref, dict_value);
+
+ // Only update kAtomicPref, kAtomicPref3, and kSplitPref.
+ pref_hash_filter_->FilterUpdate(kAtomicPref);
+ pref_hash_filter_->FilterUpdate(kAtomicPref3);
+ pref_hash_filter_->FilterUpdate(kSplitPref);
+ ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
+
+ // Update kAtomicPref3 again, nothing should be stored still.
+ base::Value* int_value5 = new base::FundamentalValue(5);
+ root_dict.Set(kAtomicPref3, int_value5);
+ ASSERT_EQ(0u, mock_pref_hash_store_->stored_paths_count());
+
+ // On FilterSerializeData, only kAtomicPref, kAtomicPref3, and kSplitPref
+ // should get a new hash.
+ pref_hash_filter_->FilterSerializeData(&root_dict);
+ ASSERT_EQ(3u, mock_pref_hash_store_->stored_paths_count());
+ MockPrefHashStore::ValuePtrStrategyPair stored_value_atomic1 =
+ mock_pref_hash_store_->stored_value(kAtomicPref);
+ ASSERT_EQ(int_value1, stored_value_atomic1.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ stored_value_atomic1.second);
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+
+ MockPrefHashStore::ValuePtrStrategyPair stored_value_atomic3 =
+ mock_pref_hash_store_->stored_value(kAtomicPref3);
+ ASSERT_EQ(int_value5, stored_value_atomic3.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ stored_value_atomic3.second);
+
+ MockPrefHashStore::ValuePtrStrategyPair stored_value_split =
+ mock_pref_hash_store_->stored_value(kSplitPref);
+ ASSERT_EQ(dict_value, stored_value_split.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_value_split.second);
+}
+
+TEST_P(PrefHashFilterTest, UnknownNullValue) {
+ ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
+ ASSERT_FALSE(pref_store_contents_->Get(kSplitPref, NULL));
+ // NULL values are always trusted by the PrefHashStore.
+ mock_pref_hash_store_->SetCheckResult(
+ kAtomicPref, PrefHashStoreTransaction::TRUSTED_NULL_VALUE);
+ mock_pref_hash_store_->SetCheckResult(
+ kSplitPref, PrefHashStoreTransaction::TRUSTED_NULL_VALUE);
+ DoFilterOnLoad(false);
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_pref_hash_store_->checked_paths_count());
+ ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+
+ MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
+ mock_pref_hash_store_->stored_value(kAtomicPref);
+ ASSERT_EQ(NULL, stored_atomic_value.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ stored_atomic_value.second);
+
+ MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
+ mock_pref_hash_store_->stored_value(kSplitPref);
+ ASSERT_EQ(NULL, stored_split_value.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_split_value.second);
+
+ // Delegate saw all prefs, two of which had the expected value_state.
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_validation_delegate_.recorded_validations_count());
+ ASSERT_EQ(2u, mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::TRUSTED_NULL_VALUE));
+ ASSERT_EQ(arraysize(kTestTrackedPrefs) - 2u,
+ mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::UNCHANGED));
+
+ const MockValidationDelegate::ValidationEvent* validated_split_pref =
+ mock_validation_delegate_.GetEventForPath(kSplitPref);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT,
+ validated_split_pref->strategy);
+ ASSERT_FALSE(validated_split_pref->is_personal);
+ const MockValidationDelegate::ValidationEvent* validated_atomic_pref =
+ mock_validation_delegate_.GetEventForPath(kAtomicPref);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ validated_atomic_pref->strategy);
+ ASSERT_TRUE(validated_atomic_pref->is_personal);
+}
+
+TEST_P(PrefHashFilterTest, InitialValueUnknown) {
+ // Ownership of these values is transfered to |pref_store_contents_|.
+ base::StringValue* string_value = new base::StringValue("string value");
+ pref_store_contents_->Set(kAtomicPref, string_value);
+
+ base::DictionaryValue* dict_value = new base::DictionaryValue;
+ dict_value->SetString("a", "foo");
+ dict_value->SetInteger("b", 1234);
+ pref_store_contents_->Set(kSplitPref, dict_value);
+
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL));
+ ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL));
+
+ mock_pref_hash_store_->SetCheckResult(
+ kAtomicPref, PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE);
+ mock_pref_hash_store_->SetCheckResult(
+ kSplitPref, PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE);
+ // If we are enforcing, expect this to report changes.
+ DoFilterOnLoad(GetParam() >= PrefHashFilter::ENFORCE_ON_LOAD);
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_pref_hash_store_->checked_paths_count());
+ ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+
+ // Delegate saw all prefs, two of which had the expected value_state.
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_validation_delegate_.recorded_validations_count());
+ ASSERT_EQ(2u, mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE));
+ ASSERT_EQ(arraysize(kTestTrackedPrefs) - 2u,
+ mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::UNCHANGED));
+
+ MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
+ mock_pref_hash_store_->stored_value(kAtomicPref);
+ MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
+ mock_pref_hash_store_->stored_value(kSplitPref);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ stored_atomic_value.second);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_split_value.second);
+ if (GetParam() == PrefHashFilter::ENFORCE_ON_LOAD) {
+ // Ensure the prefs were cleared and the hashes for NULL were restored if
+ // the current enforcement level denies seeding.
+ ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
+ ASSERT_EQ(NULL, stored_atomic_value.first);
+
+ ASSERT_FALSE(pref_store_contents_->Get(kSplitPref, NULL));
+ ASSERT_EQ(NULL, stored_split_value.first);
+
+ VerifyRecordedReset(true);
+ } else {
+ // Otherwise the values should have remained intact and the hashes should
+ // have been updated to match them.
+ const base::Value* atomic_value_in_store;
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, &atomic_value_in_store));
+ ASSERT_EQ(string_value, atomic_value_in_store);
+ ASSERT_EQ(string_value, stored_atomic_value.first);
+
+ const base::Value* split_value_in_store;
+ ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, &split_value_in_store));
+ ASSERT_EQ(dict_value, split_value_in_store);
+ ASSERT_EQ(dict_value, stored_split_value.first);
+
+ VerifyRecordedReset(false);
+ }
+}
+
+TEST_P(PrefHashFilterTest, InitialValueTrustedUnknown) {
+ // Ownership of this value is transfered to |pref_store_contents_|.
+ base::Value* string_value = new base::StringValue("test");
+ pref_store_contents_->Set(kAtomicPref, string_value);
+
+ base::DictionaryValue* dict_value = new base::DictionaryValue;
+ dict_value->SetString("a", "foo");
+ dict_value->SetInteger("b", 1234);
+ pref_store_contents_->Set(kSplitPref, dict_value);
+
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL));
+ ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL));
+
+ mock_pref_hash_store_->SetCheckResult(
+ kAtomicPref, PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE);
+ mock_pref_hash_store_->SetCheckResult(
+ kSplitPref, PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE);
+ DoFilterOnLoad(false);
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_pref_hash_store_->checked_paths_count());
+ ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+
+ // Delegate saw all prefs, two of which had the expected value_state.
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_validation_delegate_.recorded_validations_count());
+ ASSERT_EQ(2u, mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE));
+ ASSERT_EQ(arraysize(kTestTrackedPrefs) - 2u,
+ mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::UNCHANGED));
+
+ // Seeding is always allowed for trusted unknown values.
+ const base::Value* atomic_value_in_store;
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, &atomic_value_in_store));
+ ASSERT_EQ(string_value, atomic_value_in_store);
+ MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
+ mock_pref_hash_store_->stored_value(kAtomicPref);
+ ASSERT_EQ(string_value, stored_atomic_value.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ stored_atomic_value.second);
+
+ const base::Value* split_value_in_store;
+ ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, &split_value_in_store));
+ ASSERT_EQ(dict_value, split_value_in_store);
+ MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
+ mock_pref_hash_store_->stored_value(kSplitPref);
+ ASSERT_EQ(dict_value, stored_split_value.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_split_value.second);
+}
+
+TEST_P(PrefHashFilterTest, InitialValueChanged) {
+ // Ownership of this value is transfered to |pref_store_contents_|.
+ base::Value* int_value = new base::FundamentalValue(1234);
+ pref_store_contents_->Set(kAtomicPref, int_value);
+
+ base::DictionaryValue* dict_value = new base::DictionaryValue;
+ dict_value->SetString("a", "foo");
+ dict_value->SetInteger("b", 1234);
+ dict_value->SetInteger("c", 56);
+ dict_value->SetBoolean("d", false);
+ pref_store_contents_->Set(kSplitPref, dict_value);
+
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL));
+ ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL));
+
+ mock_pref_hash_store_->SetCheckResult(kAtomicPref,
+ PrefHashStoreTransaction::CHANGED);
+ mock_pref_hash_store_->SetCheckResult(kSplitPref,
+ PrefHashStoreTransaction::CHANGED);
+
+ std::vector<std::string> mock_invalid_keys;
+ mock_invalid_keys.push_back("a");
+ mock_invalid_keys.push_back("c");
+ mock_pref_hash_store_->SetInvalidKeysResult(kSplitPref, mock_invalid_keys);
+
+ DoFilterOnLoad(GetParam() >= PrefHashFilter::ENFORCE_ON_LOAD);
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_pref_hash_store_->checked_paths_count());
+ ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+
+ MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
+ mock_pref_hash_store_->stored_value(kAtomicPref);
+ MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
+ mock_pref_hash_store_->stored_value(kSplitPref);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ stored_atomic_value.second);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_split_value.second);
+ if (GetParam() == PrefHashFilter::ENFORCE_ON_LOAD) {
+ // Ensure the atomic pref was cleared and the hash for NULL was restored if
+ // the current enforcement level prevents changes.
+ ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
+ ASSERT_EQ(NULL, stored_atomic_value.first);
+
+ // The split pref on the other hand should only have been stripped of its
+ // invalid keys.
+ const base::Value* split_value_in_store;
+ ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, &split_value_in_store));
+ ASSERT_EQ(2U, dict_value->size());
+ ASSERT_FALSE(dict_value->HasKey("a"));
+ ASSERT_TRUE(dict_value->HasKey("b"));
+ ASSERT_FALSE(dict_value->HasKey("c"));
+ ASSERT_TRUE(dict_value->HasKey("d"));
+ ASSERT_EQ(dict_value, stored_split_value.first);
+
+ VerifyRecordedReset(true);
+ } else {
+ // Otherwise the value should have remained intact and the hash should have
+ // been updated to match it.
+ const base::Value* atomic_value_in_store;
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, &atomic_value_in_store));
+ ASSERT_EQ(int_value, atomic_value_in_store);
+ ASSERT_EQ(int_value, stored_atomic_value.first);
+
+ const base::Value* split_value_in_store;
+ ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, &split_value_in_store));
+ ASSERT_EQ(dict_value, split_value_in_store);
+ ASSERT_EQ(4U, dict_value->size());
+ ASSERT_TRUE(dict_value->HasKey("a"));
+ ASSERT_TRUE(dict_value->HasKey("b"));
+ ASSERT_TRUE(dict_value->HasKey("c"));
+ ASSERT_TRUE(dict_value->HasKey("d"));
+ ASSERT_EQ(dict_value, stored_split_value.first);
+
+ VerifyRecordedReset(false);
+ }
+}
+
+TEST_P(PrefHashFilterTest, EmptyCleared) {
+ ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
+ ASSERT_FALSE(pref_store_contents_->Get(kSplitPref, NULL));
+ mock_pref_hash_store_->SetCheckResult(kAtomicPref,
+ PrefHashStoreTransaction::CLEARED);
+ mock_pref_hash_store_->SetCheckResult(kSplitPref,
+ PrefHashStoreTransaction::CLEARED);
+ DoFilterOnLoad(false);
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_pref_hash_store_->checked_paths_count());
+ ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+
+ // Delegate saw all prefs, two of which had the expected value_state.
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_validation_delegate_.recorded_validations_count());
+ ASSERT_EQ(2u, mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::CLEARED));
+ ASSERT_EQ(arraysize(kTestTrackedPrefs) - 2u,
+ mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::UNCHANGED));
+
+ // Regardless of the enforcement level, the only thing that should be done is
+ // to restore the hash for NULL. The value itself should still be NULL.
+ ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
+ MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
+ mock_pref_hash_store_->stored_value(kAtomicPref);
+ ASSERT_EQ(NULL, stored_atomic_value.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ stored_atomic_value.second);
+
+ ASSERT_FALSE(pref_store_contents_->Get(kSplitPref, NULL));
+ MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
+ mock_pref_hash_store_->stored_value(kSplitPref);
+ ASSERT_EQ(NULL, stored_split_value.first);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_split_value.second);
+}
+
+TEST_P(PrefHashFilterTest, InitialValueUnchangedLegacyId) {
+ // Ownership of these values is transfered to |pref_store_contents_|.
+ base::StringValue* string_value = new base::StringValue("string value");
+ pref_store_contents_->Set(kAtomicPref, string_value);
+
+ base::DictionaryValue* dict_value = new base::DictionaryValue;
+ dict_value->SetString("a", "foo");
+ dict_value->SetInteger("b", 1234);
+ pref_store_contents_->Set(kSplitPref, dict_value);
+
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL));
+ ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, NULL));
+
+ mock_pref_hash_store_->SetCheckResult(
+ kAtomicPref, PrefHashStoreTransaction::SECURE_LEGACY);
+ mock_pref_hash_store_->SetCheckResult(
+ kSplitPref, PrefHashStoreTransaction::SECURE_LEGACY);
+ DoFilterOnLoad(false);
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_pref_hash_store_->checked_paths_count());
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+
+ // Delegate saw all prefs, two of which had the expected value_state.
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_validation_delegate_.recorded_validations_count());
+ ASSERT_EQ(2u, mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::SECURE_LEGACY));
+ ASSERT_EQ(arraysize(kTestTrackedPrefs) - 2u,
+ mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::UNCHANGED));
+
+ // Ensure that both the atomic and split hashes were restored.
+ ASSERT_EQ(2u, mock_pref_hash_store_->stored_paths_count());
+
+ // In all cases, the values should have remained intact and the hashes should
+ // have been updated to match them.
+
+ MockPrefHashStore::ValuePtrStrategyPair stored_atomic_value =
+ mock_pref_hash_store_->stored_value(kAtomicPref);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
+ stored_atomic_value.second);
+ const base::Value* atomic_value_in_store;
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, &atomic_value_in_store));
+ ASSERT_EQ(string_value, atomic_value_in_store);
+ ASSERT_EQ(string_value, stored_atomic_value.first);
+
+ MockPrefHashStore::ValuePtrStrategyPair stored_split_value =
+ mock_pref_hash_store_->stored_value(kSplitPref);
+ ASSERT_EQ(PrefHashFilter::TRACKING_STRATEGY_SPLIT, stored_split_value.second);
+ const base::Value* split_value_in_store;
+ ASSERT_TRUE(pref_store_contents_->Get(kSplitPref, &split_value_in_store));
+ ASSERT_EQ(dict_value, split_value_in_store);
+ ASSERT_EQ(dict_value, stored_split_value.first);
+
+ VerifyRecordedReset(false);
+}
+
+TEST_P(PrefHashFilterTest, DontResetReportOnly) {
+ // Ownership of these values is transfered to |pref_store_contents_|.
+ base::Value* int_value1 = new base::FundamentalValue(1);
+ base::Value* int_value2 = new base::FundamentalValue(2);
+ base::Value* report_only_val = new base::FundamentalValue(3);
+ base::DictionaryValue* report_only_split_val = new base::DictionaryValue;
+ report_only_split_val->SetInteger("a", 1234);
+ pref_store_contents_->Set(kAtomicPref, int_value1);
+ pref_store_contents_->Set(kAtomicPref2, int_value2);
+ pref_store_contents_->Set(kReportOnlyPref, report_only_val);
+ pref_store_contents_->Set(kReportOnlySplitPref, report_only_split_val);
+
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, NULL));
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref2, NULL));
+ ASSERT_TRUE(pref_store_contents_->Get(kReportOnlyPref, NULL));
+ ASSERT_TRUE(pref_store_contents_->Get(kReportOnlySplitPref, NULL));
+
+ mock_pref_hash_store_->SetCheckResult(kAtomicPref,
+ PrefHashStoreTransaction::CHANGED);
+ mock_pref_hash_store_->SetCheckResult(kAtomicPref2,
+ PrefHashStoreTransaction::CHANGED);
+ mock_pref_hash_store_->SetCheckResult(kReportOnlyPref,
+ PrefHashStoreTransaction::CHANGED);
+ mock_pref_hash_store_->SetCheckResult(kReportOnlySplitPref,
+ PrefHashStoreTransaction::CHANGED);
+
+ DoFilterOnLoad(GetParam() >= PrefHashFilter::ENFORCE_ON_LOAD);
+ // All prefs should be checked and a new hash should be stored for each tested
+ // pref.
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_pref_hash_store_->checked_paths_count());
+ ASSERT_EQ(4u, mock_pref_hash_store_->stored_paths_count());
+ ASSERT_EQ(1u, mock_pref_hash_store_->transactions_performed());
+
+ // Delegate saw all prefs, four of which had the expected value_state.
+ ASSERT_EQ(arraysize(kTestTrackedPrefs),
+ mock_validation_delegate_.recorded_validations_count());
+ ASSERT_EQ(4u, mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::CHANGED));
+ ASSERT_EQ(arraysize(kTestTrackedPrefs) - 4u,
+ mock_validation_delegate_.CountValidationsOfState(
+ PrefHashStoreTransaction::UNCHANGED));
+
+ // No matter what the enforcement level is, the report only pref should never
+ // be reset.
+ ASSERT_TRUE(pref_store_contents_->Get(kReportOnlyPref, NULL));
+ ASSERT_TRUE(pref_store_contents_->Get(kReportOnlySplitPref, NULL));
+ ASSERT_EQ(report_only_val,
+ mock_pref_hash_store_->stored_value(kReportOnlyPref).first);
+ ASSERT_EQ(report_only_split_val,
+ mock_pref_hash_store_->stored_value(kReportOnlySplitPref).first);
+
+ // All other prefs should have been reset if the enforcement level allows it.
+ if (GetParam() == PrefHashFilter::ENFORCE_ON_LOAD) {
+ ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref, NULL));
+ ASSERT_FALSE(pref_store_contents_->Get(kAtomicPref2, NULL));
+ ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kAtomicPref).first);
+ ASSERT_EQ(NULL, mock_pref_hash_store_->stored_value(kAtomicPref2).first);
+
+ VerifyRecordedReset(true);
+ } else {
+ const base::Value* value_in_store;
+ const base::Value* value_in_store2;
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref, &value_in_store));
+ ASSERT_TRUE(pref_store_contents_->Get(kAtomicPref2, &value_in_store2));
+ ASSERT_EQ(int_value1, value_in_store);
+ ASSERT_EQ(int_value1,
+ mock_pref_hash_store_->stored_value(kAtomicPref).first);
+ ASSERT_EQ(int_value2, value_in_store2);
+ ASSERT_EQ(int_value2,
+ mock_pref_hash_store_->stored_value(kAtomicPref2).first);
+
+ VerifyRecordedReset(false);
+ }
+}
+
+INSTANTIATE_TEST_CASE_P(PrefHashFilterTestInstance,
+ PrefHashFilterTest,
+ testing::Values(PrefHashFilter::NO_ENFORCEMENT,
+ PrefHashFilter::ENFORCE_ON_LOAD));
diff --git a/chromium/components/user_prefs/tracked/pref_hash_store.h b/chromium/components/user_prefs/tracked/pref_hash_store.h
new file mode 100644
index 00000000000..9ab0f48aa6d
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_store.h
@@ -0,0 +1,28 @@
+// 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_PREFS_TRACKED_PREF_HASH_STORE_H_
+#define COMPONENTS_PREFS_TRACKED_PREF_HASH_STORE_H_
+
+#include "base/memory/scoped_ptr.h"
+
+class HashStoreContents;
+class PrefHashStoreTransaction;
+
+// Holds the configuration and implementation used to calculate and verify
+// preference MACs.
+// TODO(gab): Rename this class as it is no longer a store.
+class PrefHashStore {
+ public:
+ virtual ~PrefHashStore() {}
+
+ // Returns a PrefHashStoreTransaction which can be used to perform a series
+ // of operations on the hash store. |storage| MAY be used as the backing store
+ // depending on the implementation. Therefore the HashStoreContents used for
+ // related transactions should correspond to the same underlying data store.
+ virtual scoped_ptr<PrefHashStoreTransaction> BeginTransaction(
+ scoped_ptr<HashStoreContents> storage) = 0;
+};
+
+#endif // COMPONENTS_PREFS_TRACKED_PREF_HASH_STORE_H_
diff --git a/chromium/components/user_prefs/tracked/pref_hash_store_impl.cc b/chromium/components/user_prefs/tracked/pref_hash_store_impl.cc
new file mode 100644
index 00000000000..dd862221d57
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_store_impl.cc
@@ -0,0 +1,308 @@
+// 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/user_prefs/tracked/pref_hash_store_impl.h"
+
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "base/values.h"
+#include "components/user_prefs/tracked/hash_store_contents.h"
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+
+class PrefHashStoreImpl::PrefHashStoreTransactionImpl
+ : public PrefHashStoreTransaction {
+ public:
+ // Constructs a PrefHashStoreTransactionImpl which can use the private
+ // members of its |outer| PrefHashStoreImpl.
+ PrefHashStoreTransactionImpl(PrefHashStoreImpl* outer,
+ scoped_ptr<HashStoreContents> storage);
+ ~PrefHashStoreTransactionImpl() override;
+
+ // PrefHashStoreTransaction implementation.
+ ValueState CheckValue(const std::string& path,
+ const base::Value* value) const override;
+ void StoreHash(const std::string& path, const base::Value* value) override;
+ ValueState CheckSplitValue(
+ const std::string& path,
+ const base::DictionaryValue* initial_split_value,
+ std::vector<std::string>* invalid_keys) const override;
+ void StoreSplitHash(const std::string& path,
+ const base::DictionaryValue* split_value) override;
+ bool HasHash(const std::string& path) const override;
+ void ImportHash(const std::string& path, const base::Value* hash) override;
+ void ClearHash(const std::string& path) override;
+ bool IsSuperMACValid() const override;
+ bool StampSuperMac() override;
+
+ private:
+ bool GetSplitMacs(const std::string& path,
+ std::map<std::string, std::string>* split_macs) const;
+
+ HashStoreContents* contents() {
+ return outer_->legacy_hash_store_contents_
+ ? outer_->legacy_hash_store_contents_.get()
+ : contents_.get();
+ }
+
+ const HashStoreContents* contents() const {
+ return outer_->legacy_hash_store_contents_
+ ? outer_->legacy_hash_store_contents_.get()
+ : contents_.get();
+ }
+
+ PrefHashStoreImpl* outer_;
+ scoped_ptr<HashStoreContents> contents_;
+
+ bool super_mac_valid_;
+ bool super_mac_dirty_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefHashStoreTransactionImpl);
+};
+
+PrefHashStoreImpl::PrefHashStoreImpl(const std::string& seed,
+ const std::string& device_id,
+ bool use_super_mac)
+ : pref_hash_calculator_(seed, device_id), use_super_mac_(use_super_mac) {
+}
+
+PrefHashStoreImpl::~PrefHashStoreImpl() {
+}
+
+void PrefHashStoreImpl::set_legacy_hash_store_contents(
+ scoped_ptr<HashStoreContents> legacy_hash_store_contents) {
+ legacy_hash_store_contents_ = legacy_hash_store_contents.Pass();
+}
+
+scoped_ptr<PrefHashStoreTransaction> PrefHashStoreImpl::BeginTransaction(
+ scoped_ptr<HashStoreContents> storage) {
+ return scoped_ptr<PrefHashStoreTransaction>(
+ new PrefHashStoreTransactionImpl(this, storage.Pass()));
+}
+
+PrefHashStoreImpl::PrefHashStoreTransactionImpl::PrefHashStoreTransactionImpl(
+ PrefHashStoreImpl* outer,
+ scoped_ptr<HashStoreContents> storage)
+ : outer_(outer),
+ contents_(storage.Pass()),
+ super_mac_valid_(false),
+ super_mac_dirty_(false) {
+ if (!outer_->use_super_mac_)
+ return;
+
+ // The store must be initialized and have a valid super MAC to be trusted.
+
+ const base::DictionaryValue* store_contents = contents()->GetContents();
+ if (!store_contents)
+ return;
+
+ std::string super_mac = contents()->GetSuperMac();
+ if (super_mac.empty())
+ return;
+
+ super_mac_valid_ = outer_->pref_hash_calculator_.Validate(
+ contents()->hash_store_id(), store_contents,
+ super_mac) == PrefHashCalculator::VALID;
+}
+
+PrefHashStoreImpl::PrefHashStoreTransactionImpl::
+ ~PrefHashStoreTransactionImpl() {
+ if (super_mac_dirty_ && outer_->use_super_mac_) {
+ // Get the dictionary of hashes (or NULL if it doesn't exist).
+ const base::DictionaryValue* hashes_dict = contents()->GetContents();
+ contents()->SetSuperMac(outer_->pref_hash_calculator_.Calculate(
+ contents()->hash_store_id(), hashes_dict));
+ }
+}
+
+PrefHashStoreTransaction::ValueState
+PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckValue(
+ const std::string& path,
+ const base::Value* initial_value) const {
+ const base::DictionaryValue* hashes_dict = contents()->GetContents();
+
+ std::string last_hash;
+ if (hashes_dict)
+ hashes_dict->GetString(path, &last_hash);
+
+ if (last_hash.empty()) {
+ // In the absence of a hash for this pref, always trust a NULL value, but
+ // only trust an existing value if the initial hashes dictionary is trusted.
+ if (!initial_value)
+ return TRUSTED_NULL_VALUE;
+ else if (super_mac_valid_)
+ return TRUSTED_UNKNOWN_VALUE;
+ else
+ return UNTRUSTED_UNKNOWN_VALUE;
+ }
+
+ PrefHashCalculator::ValidationResult validation_result =
+ outer_->pref_hash_calculator_.Validate(path, initial_value, last_hash);
+ switch (validation_result) {
+ case PrefHashCalculator::VALID:
+ return UNCHANGED;
+ case PrefHashCalculator::VALID_SECURE_LEGACY:
+ return SECURE_LEGACY;
+ case PrefHashCalculator::INVALID:
+ return initial_value ? CHANGED : CLEARED;
+ }
+ NOTREACHED() << "Unexpected PrefHashCalculator::ValidationResult: "
+ << validation_result;
+ return UNTRUSTED_UNKNOWN_VALUE;
+}
+
+void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreHash(
+ const std::string& path,
+ const base::Value* new_value) {
+ const std::string mac =
+ outer_->pref_hash_calculator_.Calculate(path, new_value);
+ (*contents()->GetMutableContents())->SetString(path, mac);
+ super_mac_dirty_ = true;
+}
+
+PrefHashStoreTransaction::ValueState
+PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckSplitValue(
+ const std::string& path,
+ const base::DictionaryValue* initial_split_value,
+ std::vector<std::string>* invalid_keys) const {
+ DCHECK(invalid_keys && invalid_keys->empty());
+
+ std::map<std::string, std::string> split_macs;
+ const bool has_hashes = GetSplitMacs(path, &split_macs);
+
+ // Treat NULL and empty the same; otherwise we would need to store a hash for
+ // the entire dictionary (or some other special beacon) to differentiate these
+ // two cases which are really the same for dictionaries.
+ if (!initial_split_value || initial_split_value->empty())
+ return has_hashes ? CLEARED : UNCHANGED;
+
+ if (!has_hashes)
+ return super_mac_valid_ ? TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE;
+
+ bool has_secure_legacy_id_hashes = false;
+ std::string keyed_path(path);
+ keyed_path.push_back('.');
+ const size_t common_part_length = keyed_path.length();
+ for (base::DictionaryValue::Iterator it(*initial_split_value); !it.IsAtEnd();
+ it.Advance()) {
+ std::map<std::string, std::string>::iterator entry =
+ split_macs.find(it.key());
+ if (entry == split_macs.end()) {
+ invalid_keys->push_back(it.key());
+ } else {
+ // Keep the common part from the old |keyed_path| and replace the key to
+ // get the new |keyed_path|.
+ keyed_path.replace(common_part_length, std::string::npos, it.key());
+ switch (outer_->pref_hash_calculator_.Validate(keyed_path, &it.value(),
+ entry->second)) {
+ case PrefHashCalculator::VALID:
+ break;
+ case SECURE_LEGACY:
+ // Secure legacy device IDs based hashes are still accepted, but we
+ // should make sure to notify the caller for him to update the legacy
+ // hashes.
+ has_secure_legacy_id_hashes = true;
+ break;
+ case PrefHashCalculator::INVALID:
+ invalid_keys->push_back(it.key());
+ break;
+ }
+ // Remove processed MACs, remaining MACs at the end will also be
+ // considered invalid.
+ split_macs.erase(entry);
+ }
+ }
+
+ // Anything left in the map is missing from the data.
+ for (std::map<std::string, std::string>::const_iterator it =
+ split_macs.begin();
+ it != split_macs.end(); ++it) {
+ invalid_keys->push_back(it->first);
+ }
+
+ return invalid_keys->empty()
+ ? (has_secure_legacy_id_hashes ? SECURE_LEGACY : UNCHANGED)
+ : CHANGED;
+}
+
+void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreSplitHash(
+ const std::string& path,
+ const base::DictionaryValue* split_value) {
+ scoped_ptr<HashStoreContents::MutableDictionary> mutable_dictionary =
+ contents()->GetMutableContents();
+ (*mutable_dictionary)->Remove(path, NULL);
+
+ if (split_value) {
+ std::string keyed_path(path);
+ keyed_path.push_back('.');
+ const size_t common_part_length = keyed_path.length();
+ for (base::DictionaryValue::Iterator it(*split_value); !it.IsAtEnd();
+ it.Advance()) {
+ // Keep the common part from the old |keyed_path| and replace the key to
+ // get the new |keyed_path|.
+ keyed_path.replace(common_part_length, std::string::npos, it.key());
+ (*mutable_dictionary)
+ ->SetString(keyed_path, outer_->pref_hash_calculator_.Calculate(
+ keyed_path, &it.value()));
+ }
+ }
+ super_mac_dirty_ = true;
+}
+
+bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs(
+ const std::string& key,
+ std::map<std::string, std::string>* split_macs) const {
+ DCHECK(split_macs);
+ DCHECK(split_macs->empty());
+
+ const base::DictionaryValue* hashes_dict = contents()->GetContents();
+ const base::DictionaryValue* split_mac_dictionary = NULL;
+ if (!hashes_dict || !hashes_dict->GetDictionary(key, &split_mac_dictionary))
+ return false;
+ for (base::DictionaryValue::Iterator it(*split_mac_dictionary); !it.IsAtEnd();
+ it.Advance()) {
+ std::string mac_string;
+ if (!it.value().GetAsString(&mac_string)) {
+ NOTREACHED();
+ continue;
+ }
+ split_macs->insert(make_pair(it.key(), mac_string));
+ }
+ return true;
+}
+
+bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::HasHash(
+ const std::string& path) const {
+ const base::DictionaryValue* hashes_dict = contents()->GetContents();
+ return hashes_dict && hashes_dict->Get(path, NULL);
+}
+
+void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ImportHash(
+ const std::string& path,
+ const base::Value* hash) {
+ DCHECK(hash);
+
+ (*contents()->GetMutableContents())->Set(path, hash->DeepCopy());
+
+ if (super_mac_valid_)
+ super_mac_dirty_ = true;
+}
+
+void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ClearHash(
+ const std::string& path) {
+ if ((*contents()->GetMutableContents())->RemovePath(path, NULL) &&
+ super_mac_valid_) {
+ super_mac_dirty_ = true;
+ }
+}
+
+bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::IsSuperMACValid() const {
+ return super_mac_valid_;
+}
+
+bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::StampSuperMac() {
+ if (!outer_->use_super_mac_ || super_mac_valid_)
+ return false;
+ super_mac_dirty_ = true;
+ return true;
+}
diff --git a/chromium/components/user_prefs/tracked/pref_hash_store_impl.h b/chromium/components/user_prefs/tracked/pref_hash_store_impl.h
new file mode 100644
index 00000000000..97442009d12
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_store_impl.h
@@ -0,0 +1,67 @@
+// 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_USER_PREFS_TRACKED_PREF_HASH_STORE_IMPL_H_
+#define COMPONENTS_USER_PREFS_TRACKED_PREF_HASH_STORE_IMPL_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/user_prefs/tracked/pref_hash_calculator.h"
+#include "components/user_prefs/tracked/pref_hash_store.h"
+
+class HashStoreContents;
+class PrefHashStoreTransaction;
+
+// Implements PrefHashStoreImpl by storing preference hashes in a
+// HashStoreContents.
+class PrefHashStoreImpl : public PrefHashStore {
+ public:
+ enum StoreVersion {
+ // No hashes have been stored in this PrefHashStore yet.
+ VERSION_UNINITIALIZED = 0,
+ // The hashes in this PrefHashStore were stored before the introduction
+ // of a version number and should be re-initialized.
+ VERSION_PRE_MIGRATION = 1,
+ // The hashes in this PrefHashStore were stored using the latest algorithm.
+ VERSION_LATEST = 2,
+ };
+
+ // Constructs a PrefHashStoreImpl that calculates hashes using
+ // |seed| and |device_id| and stores them in |contents|.
+ //
+ // The same |seed| and |device_id| must be used to load and validate
+ // previously stored hashes in |contents|.
+ PrefHashStoreImpl(const std::string& seed,
+ const std::string& device_id,
+ bool use_super_mac);
+
+ ~PrefHashStoreImpl() override;
+
+ // Provides an external HashStoreContents implementation to be used.
+ // BeginTransaction() will ignore |storage| if this is provided.
+ void set_legacy_hash_store_contents(
+ scoped_ptr<HashStoreContents> legacy_hash_store_contents);
+
+ // Clears the contents of this PrefHashStore. |IsInitialized()| will return
+ // false after this call.
+ void Reset();
+
+ // PrefHashStore implementation.
+ scoped_ptr<PrefHashStoreTransaction> BeginTransaction(
+ scoped_ptr<HashStoreContents> storage) override;
+
+ private:
+ class PrefHashStoreTransactionImpl;
+
+ const PrefHashCalculator pref_hash_calculator_;
+ scoped_ptr<HashStoreContents> legacy_hash_store_contents_;
+ bool use_super_mac_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefHashStoreImpl);
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_PREF_HASH_STORE_IMPL_H_
diff --git a/chromium/components/user_prefs/tracked/pref_hash_store_impl_unittest.cc b/chromium/components/user_prefs/tracked/pref_hash_store_impl_unittest.cc
new file mode 100644
index 00000000000..8ec8ffaf277
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_store_impl_unittest.cc
@@ -0,0 +1,474 @@
+// 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/user_prefs/tracked/pref_hash_store_impl.h"
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/values.h"
+#include "components/user_prefs/tracked/dictionary_hash_store_contents.h"
+#include "components/user_prefs/tracked/hash_store_contents.h"
+#include "components/user_prefs/tracked/pref_hash_store_impl.h"
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class PrefHashStoreImplTest : public testing::Test {
+ protected:
+ scoped_ptr<HashStoreContents> CreateHashStoreContents() {
+ return scoped_ptr<HashStoreContents>(
+ new DictionaryHashStoreContents(&pref_store_contents_));
+ }
+
+ private:
+ base::DictionaryValue pref_store_contents_;
+};
+
+TEST_F(PrefHashStoreImplTest, AtomicHashStoreAndCheck) {
+ base::StringValue string_1("string1");
+ base::StringValue string_2("string2");
+
+ {
+ // 32 NULL bytes is the seed that was used to generate the legacy hash.
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+
+ // Only NULL should be trusted in the absence of a hash.
+ EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE,
+ transaction->CheckValue("path1", &string_1));
+ EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_NULL_VALUE,
+ transaction->CheckValue("path1", NULL));
+
+ transaction->StoreHash("path1", &string_1);
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", &string_1));
+ EXPECT_EQ(PrefHashStoreTransaction::CLEARED,
+ transaction->CheckValue("path1", NULL));
+ transaction->StoreHash("path1", NULL);
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", NULL));
+ EXPECT_EQ(PrefHashStoreTransaction::CHANGED,
+ transaction->CheckValue("path1", &string_2));
+
+ base::DictionaryValue dict;
+ dict.Set("a", new base::StringValue("foo"));
+ dict.Set("d", new base::StringValue("bad"));
+ dict.Set("b", new base::StringValue("bar"));
+ dict.Set("c", new base::StringValue("baz"));
+
+ transaction->StoreHash("path1", &dict);
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", &dict));
+ }
+
+ ASSERT_FALSE(CreateHashStoreContents()->GetSuperMac().empty());
+
+ {
+ // |pref_hash_store2| should trust its initial hashes dictionary and thus
+ // trust new unknown values.
+ PrefHashStoreImpl pref_hash_store2(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store2.BeginTransaction(CreateHashStoreContents()));
+ EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE,
+ transaction->CheckValue("new_path", &string_1));
+ EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE,
+ transaction->CheckValue("new_path", &string_2));
+ EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_NULL_VALUE,
+ transaction->CheckValue("new_path", NULL));
+ }
+
+ // Manually corrupt the super MAC.
+ CreateHashStoreContents()->SetSuperMac(std::string(64, 'A'));
+
+ {
+ // |pref_hash_store3| should no longer trust its initial hashes dictionary
+ // and thus shouldn't trust non-NULL unknown values.
+ PrefHashStoreImpl pref_hash_store3(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store3.BeginTransaction(CreateHashStoreContents()));
+ EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE,
+ transaction->CheckValue("new_path", &string_1));
+ EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE,
+ transaction->CheckValue("new_path", &string_2));
+ EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_NULL_VALUE,
+ transaction->CheckValue("new_path", NULL));
+ }
+}
+
+TEST_F(PrefHashStoreImplTest, ImportExportOperations) {
+ base::StringValue string_1("string1");
+ base::StringValue string_2("string2");
+
+ // Initial state: no super MAC.
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+ ASSERT_FALSE(transaction->IsSuperMACValid());
+
+ ASSERT_FALSE(transaction->HasHash("path1"));
+
+ // Storing a hash will stamp the super MAC.
+ transaction->StoreHash("path1", &string_1);
+
+ ASSERT_TRUE(transaction->HasHash("path1"));
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", &string_1));
+ EXPECT_EQ(PrefHashStoreTransaction::CHANGED,
+ transaction->CheckValue("path1", &string_2));
+ }
+
+ // Make a copy of the stored hash for future use.
+ const base::Value* hash = NULL;
+ ASSERT_TRUE(CreateHashStoreContents()->GetContents()->Get("path1", &hash));
+ scoped_ptr<base::Value> path_1_string_1_hash_copy(hash->DeepCopy());
+ hash = NULL;
+
+ // Verify that the super MAC was stamped.
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+ ASSERT_TRUE(transaction->IsSuperMACValid());
+ ASSERT_TRUE(transaction->HasHash("path1"));
+
+ // Clearing the hash should preserve validity.
+ transaction->ClearHash("path1");
+
+ // The effects of the clear should be immediately visible.
+ ASSERT_FALSE(transaction->HasHash("path1"));
+ EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_NULL_VALUE,
+ transaction->CheckValue("path1", NULL));
+ EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE,
+ transaction->CheckValue("path1", &string_1));
+ }
+
+ // Verify that validity was preserved and that the clear took effect.
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+ ASSERT_TRUE(transaction->IsSuperMACValid());
+ ASSERT_FALSE(transaction->HasHash("path1"));
+ }
+
+ // Invalidate the super MAC.
+ CreateHashStoreContents()->SetSuperMac(std::string());
+
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+ ASSERT_FALSE(transaction->IsSuperMACValid());
+ ASSERT_FALSE(transaction->HasHash("path1"));
+
+ // An import should preserve invalidity.
+ transaction->ImportHash("path1", path_1_string_1_hash_copy.get());
+
+ ASSERT_TRUE(transaction->HasHash("path1"));
+
+ // The imported hash should be usable for validating the original value.
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", &string_1));
+ }
+
+ // Verify that invalidity was preserved and that the import took effect.
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+ ASSERT_FALSE(transaction->IsSuperMACValid());
+ ASSERT_TRUE(transaction->HasHash("path1"));
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", &string_1));
+
+ // After clearing the hash, non-null values are UNTRUSTED_UNKNOWN.
+ transaction->ClearHash("path1");
+
+ EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_NULL_VALUE,
+ transaction->CheckValue("path1", NULL));
+ EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE,
+ transaction->CheckValue("path1", &string_1));
+ }
+
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+ ASSERT_FALSE(transaction->IsSuperMACValid());
+
+ // Test StampSuperMac.
+ transaction->StampSuperMac();
+ }
+
+ // Verify that the store is now valid.
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+ ASSERT_TRUE(transaction->IsSuperMACValid());
+
+ // Store the hash of a different value to test an "over-import".
+ transaction->StoreHash("path1", &string_2);
+ EXPECT_EQ(PrefHashStoreTransaction::CHANGED,
+ transaction->CheckValue("path1", &string_1));
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", &string_2));
+ }
+
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+ ASSERT_TRUE(transaction->IsSuperMACValid());
+
+ // "Over-import". An import should preserve validity.
+ transaction->ImportHash("path1", path_1_string_1_hash_copy.get());
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", &string_1));
+ EXPECT_EQ(PrefHashStoreTransaction::CHANGED,
+ transaction->CheckValue("path1", &string_2));
+ }
+
+ // Verify that validity was preserved and the "over-import" took effect.
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+ ASSERT_TRUE(transaction->IsSuperMACValid());
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", &string_1));
+ EXPECT_EQ(PrefHashStoreTransaction::CHANGED,
+ transaction->CheckValue("path1", &string_2));
+ }
+}
+
+TEST_F(PrefHashStoreImplTest, SuperMACDisabled) {
+ base::StringValue string_1("string1");
+ base::StringValue string_2("string2");
+
+ {
+ // Pass |use_super_mac| => false.
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", false);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+
+ transaction->StoreHash("path1", &string_2);
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", &string_2));
+ }
+
+ ASSERT_TRUE(CreateHashStoreContents()->GetSuperMac().empty());
+
+ {
+ PrefHashStoreImpl pref_hash_store2(std::string(32, 0), "device_id", false);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store2.BeginTransaction(CreateHashStoreContents()));
+ EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE,
+ transaction->CheckValue("new_path", &string_1));
+ }
+}
+
+TEST_F(PrefHashStoreImplTest, SplitHashStoreAndCheck) {
+ base::DictionaryValue dict;
+ dict.Set("a", new base::StringValue("to be replaced"));
+ dict.Set("b", new base::StringValue("same"));
+ dict.Set("o", new base::StringValue("old"));
+
+ base::DictionaryValue modified_dict;
+ modified_dict.Set("a", new base::StringValue("replaced"));
+ modified_dict.Set("b", new base::StringValue("same"));
+ modified_dict.Set("c", new base::StringValue("new"));
+
+ base::DictionaryValue empty_dict;
+
+ std::vector<std::string> invalid_keys;
+
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+
+ // No hashes stored yet and hashes dictionary is empty (and thus not
+ // trusted).
+ EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE,
+ transaction->CheckSplitValue("path1", &dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+
+ transaction->StoreSplitHash("path1", &dict);
+
+ // Verify match post storage.
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckSplitValue("path1", &dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+
+ // Verify new path is still unknown.
+ EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE,
+ transaction->CheckSplitValue("path2", &dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+
+ // Verify NULL or empty dicts are declared as having been cleared.
+ EXPECT_EQ(PrefHashStoreTransaction::CLEARED,
+ transaction->CheckSplitValue("path1", NULL, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+ EXPECT_EQ(
+ PrefHashStoreTransaction::CLEARED,
+ transaction->CheckSplitValue("path1", &empty_dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+
+ // Verify changes are properly detected.
+ EXPECT_EQ(
+ PrefHashStoreTransaction::CHANGED,
+ transaction->CheckSplitValue("path1", &modified_dict, &invalid_keys));
+ std::vector<std::string> expected_invalid_keys1;
+ expected_invalid_keys1.push_back("a");
+ expected_invalid_keys1.push_back("c");
+ expected_invalid_keys1.push_back("o");
+ EXPECT_EQ(expected_invalid_keys1, invalid_keys);
+ invalid_keys.clear();
+
+ // Verify |dict| still matches post check.
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckSplitValue("path1", &dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+
+ // Store hash for |modified_dict|.
+ transaction->StoreSplitHash("path1", &modified_dict);
+
+ // Verify |modified_dict| is now the one that verifies correctly.
+ EXPECT_EQ(
+ PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckSplitValue("path1", &modified_dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+
+ // Verify old dict no longer matches.
+ EXPECT_EQ(PrefHashStoreTransaction::CHANGED,
+ transaction->CheckSplitValue("path1", &dict, &invalid_keys));
+ std::vector<std::string> expected_invalid_keys2;
+ expected_invalid_keys2.push_back("a");
+ expected_invalid_keys2.push_back("o");
+ expected_invalid_keys2.push_back("c");
+ EXPECT_EQ(expected_invalid_keys2, invalid_keys);
+ invalid_keys.clear();
+ }
+
+ {
+ // |pref_hash_store2| should trust its initial hashes dictionary and thus
+ // trust new unknown values.
+ PrefHashStoreImpl pref_hash_store2(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store2.BeginTransaction(CreateHashStoreContents()));
+ EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE,
+ transaction->CheckSplitValue("new_path", &dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+ }
+
+ // Manually corrupt the super MAC.
+ CreateHashStoreContents()->SetSuperMac(std::string(64, 'A'));
+
+ {
+ // |pref_hash_store3| should no longer trust its initial hashes dictionary
+ // and thus shouldn't trust unknown values.
+ PrefHashStoreImpl pref_hash_store3(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store3.BeginTransaction(CreateHashStoreContents()));
+ EXPECT_EQ(PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE,
+ transaction->CheckSplitValue("new_path", &dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+ }
+}
+
+TEST_F(PrefHashStoreImplTest, EmptyAndNULLSplitDict) {
+ base::DictionaryValue empty_dict;
+
+ std::vector<std::string> invalid_keys;
+
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+
+ // Store hashes for a random dict to be overwritten below.
+ base::DictionaryValue initial_dict;
+ initial_dict.Set("a", new base::StringValue("foo"));
+ transaction->StoreSplitHash("path1", &initial_dict);
+
+ // Verify stored empty dictionary matches NULL and empty dictionary back.
+ transaction->StoreSplitHash("path1", &empty_dict);
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckSplitValue("path1", NULL, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+ EXPECT_EQ(
+ PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckSplitValue("path1", &empty_dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+
+ // Same when storing NULL directly.
+ transaction->StoreSplitHash("path1", NULL);
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckSplitValue("path1", NULL, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+ EXPECT_EQ(
+ PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckSplitValue("path1", &empty_dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+ }
+
+ {
+ // |pref_hash_store2| should trust its initial hashes dictionary (and thus
+ // trust new unknown values) even though the last action done was to clear
+ // the hashes for path1 by setting its value to NULL (this is a regression
+ // test ensuring that the internal action of clearing some hashes does
+ // update the stored hash of hashes).
+ PrefHashStoreImpl pref_hash_store2(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store2.BeginTransaction(CreateHashStoreContents()));
+
+ base::DictionaryValue tested_dict;
+ tested_dict.Set("a", new base::StringValue("foo"));
+ tested_dict.Set("b", new base::StringValue("bar"));
+ EXPECT_EQ(
+ PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE,
+ transaction->CheckSplitValue("new_path", &tested_dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+ }
+}
+
+// Test that the PrefHashStore returns TRUSTED_UNKNOWN_VALUE when checking for
+// a split preference even if there is an existing atomic preference's hash
+// stored. There is no point providing a migration path for preferences
+// switching strategies after their initial release as split preferences are
+// turned into split preferences specifically because the atomic hash isn't
+// considered useful.
+TEST_F(PrefHashStoreImplTest, TrustedUnknownSplitValueFromExistingAtomic) {
+ base::StringValue string("string1");
+
+ base::DictionaryValue dict;
+ dict.Set("a", new base::StringValue("foo"));
+ dict.Set("d", new base::StringValue("bad"));
+ dict.Set("b", new base::StringValue("bar"));
+ dict.Set("c", new base::StringValue("baz"));
+
+ {
+ PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store.BeginTransaction(CreateHashStoreContents()));
+
+ transaction->StoreHash("path1", &string);
+ EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
+ transaction->CheckValue("path1", &string));
+ }
+
+ {
+ // Load a new |pref_hash_store2| in which the hashes dictionary is trusted.
+ PrefHashStoreImpl pref_hash_store2(std::string(32, 0), "device_id", true);
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ pref_hash_store2.BeginTransaction(CreateHashStoreContents()));
+ std::vector<std::string> invalid_keys;
+ EXPECT_EQ(PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE,
+ transaction->CheckSplitValue("path1", &dict, &invalid_keys));
+ EXPECT_TRUE(invalid_keys.empty());
+ }
+}
diff --git a/chromium/components/user_prefs/tracked/pref_hash_store_transaction.h b/chromium/components/user_prefs/tracked/pref_hash_store_transaction.h
new file mode 100644
index 00000000000..b8e2cf75e75
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_hash_store_transaction.h
@@ -0,0 +1,94 @@
+// 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_USER_PREFS_TRACKED_PREF_HASH_STORE_TRANSACTION_H_
+#define COMPONENTS_USER_PREFS_TRACKED_PREF_HASH_STORE_TRANSACTION_H_
+
+#include <string>
+#include <vector>
+
+namespace base {
+class DictionaryValue;
+class Value;
+} // namespace base
+
+// Used to perform a series of checks/transformations on a PrefHashStore.
+class PrefHashStoreTransaction {
+ public:
+ enum ValueState {
+ // The preference value corresponds to its stored hash.
+ UNCHANGED,
+ // The preference has been cleared since the last hash.
+ CLEARED,
+ // The preference value corresponds to its stored hash, but the hash was
+ // calculated using a deprecated hash algorithm which is just as safe as
+ // the current one.
+ SECURE_LEGACY,
+ // The preference value has been changed since the last hash.
+ CHANGED,
+ // No stored hash exists for the preference value.
+ UNTRUSTED_UNKNOWN_VALUE,
+ // No stored hash exists for the preference value, but the current set of
+ // hashes stored is trusted and thus this value can safely be seeded. This
+ // happens when all hashes are already properly seeded and a newly
+ // tracked value needs to be seeded).
+ TRUSTED_UNKNOWN_VALUE,
+ // NULL values are inherently trusted.
+ TRUSTED_NULL_VALUE,
+ };
+
+ // Finalizes any remaining work after the transaction has been performed.
+ virtual ~PrefHashStoreTransaction() {}
+
+ // Checks |initial_value| against the existing stored value hash.
+ virtual ValueState CheckValue(const std::string& path,
+ const base::Value* initial_value) const = 0;
+
+ // Stores a hash of the current |value| of the preference at |path|.
+ virtual void StoreHash(const std::string& path, const base::Value* value) = 0;
+
+ // Checks |initial_value| against the existing stored hashes for the split
+ // preference at |path|. |initial_split_value| being an empty dictionary or
+ // NULL is equivalent. |invalid_keys| must initially be empty. |invalid_keys|
+ // will not be modified unless the return value is CHANGED, in which case it
+ // will be filled with the keys that are considered invalid (unknown or
+ // changed).
+ virtual ValueState CheckSplitValue(
+ const std::string& path,
+ const base::DictionaryValue* initial_split_value,
+ std::vector<std::string>* invalid_keys) const = 0;
+
+ // Stores hashes for the |value| of the split preference at |path|.
+ // |split_value| being an empty dictionary or NULL is equivalent.
+ virtual void StoreSplitHash(const std::string& path,
+ const base::DictionaryValue* split_value) = 0;
+
+ // Indicates whether the store contains a hash for the preference at |path|.
+ virtual bool HasHash(const std::string& path) const = 0;
+
+ // Sets the hash for the preference at |path|.
+ // If |path| is a split preference |hash| must be a DictionaryValue whose
+ // keys are keys in the split preference and whose values are MACs of the
+ // corresponding values in the split preference.
+ // If |path| is an atomic preference |hash| must be a StringValue
+ // containing a MAC of the preference value.
+ // |hash| should originate from a PrefHashStore sharing the same MAC
+ // parameters as this transaction's store.
+ // The (in)validity of the super MAC will be maintained by this call.
+ virtual void ImportHash(const std::string& path, const base::Value* hash) = 0;
+
+ // Removes the hash stored at |path|. The (in)validity of the super MAC will
+ // be maintained by this call.
+ virtual void ClearHash(const std::string& path) = 0;
+
+ // Indicates whether the super MAC was successfully verified at the beginning
+ // of this transaction.
+ virtual bool IsSuperMACValid() const = 0;
+
+ // Forces a valid super MAC to be stored when this transaction terminates.
+ // Returns true if this results in a change to the store contents.
+ virtual bool StampSuperMac() = 0;
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_PREF_HASH_STORE_TRANSACTION_H_
diff --git a/chromium/components/user_prefs/tracked/pref_names.cc b/chromium/components/user_prefs/tracked/pref_names.cc
new file mode 100644
index 00000000000..a6c73a65228
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_names.cc
@@ -0,0 +1,13 @@
+// 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/user_prefs/tracked/pref_names.h"
+
+namespace user_prefs {
+
+// A timestamp (stored in base::Time::ToInternalValue format) of the last time
+// a preference was reset.
+const char kPreferenceResetTime[] = "prefs.preference_reset_time";
+
+} // namespace user_prefs
diff --git a/chromium/components/user_prefs/tracked/pref_names.h b/chromium/components/user_prefs/tracked/pref_names.h
new file mode 100644
index 00000000000..80aa6bf5d07
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_names.h
@@ -0,0 +1,14 @@
+// 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_USER_PREFS_TRACKED_PREF_NAMES_H_
+#define COMPONENTS_USER_PREFS_TRACKED_PREF_NAMES_H_
+
+namespace user_prefs {
+
+extern const char kPreferenceResetTime[];
+
+} // namespace user_prefs
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_PREF_NAMES_H_
diff --git a/chromium/components/user_prefs/tracked/pref_service_hash_store_contents.cc b/chromium/components/user_prefs/tracked/pref_service_hash_store_contents.cc
new file mode 100644
index 00000000000..122fa472413
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_service_hash_store_contents.cc
@@ -0,0 +1,146 @@
+// 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/user_prefs/tracked/pref_service_hash_store_contents.h"
+
+#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/pref_service.h"
+#include "base/prefs/scoped_user_pref_update.h"
+#include "base/values.h"
+
+namespace {
+
+// Implements get-or-create of a dictionary value and holds a
+// DictionaryPrefUpdate.
+class PrefServiceMutableDictionary
+ : public HashStoreContents::MutableDictionary {
+ public:
+ // Creates an instance that provides mutable access to a dictionary value
+ // named |key| that is a child of |kProfilePreferenceHashes| in
+ // |prefs|.
+ PrefServiceMutableDictionary(const std::string& key,
+ PrefService* pref_service);
+
+ // HashStoreContents::MutableDictionary implementation
+ base::DictionaryValue* operator->() override;
+
+ private:
+ const std::string key_;
+ DictionaryPrefUpdate update_;
+};
+
+PrefServiceMutableDictionary::PrefServiceMutableDictionary(
+ const std::string& key,
+ PrefService* pref_service)
+ : key_(key),
+ update_(pref_service,
+ PrefServiceHashStoreContents::kProfilePreferenceHashes) {
+ DCHECK(!key_.empty());
+}
+
+base::DictionaryValue* PrefServiceMutableDictionary::operator->() {
+ base::DictionaryValue* dictionary = NULL;
+ if (!update_->GetDictionaryWithoutPathExpansion(key_, &dictionary)) {
+ dictionary = new base::DictionaryValue;
+ update_->SetWithoutPathExpansion(key_, dictionary);
+ }
+ return dictionary;
+}
+
+} // namespace
+
+// static
+const char PrefServiceHashStoreContents::kProfilePreferenceHashes[] =
+ "profile.preference_hashes";
+
+// static
+const char PrefServiceHashStoreContents::kHashOfHashesDict[] = "hash_of_hashes";
+
+// static
+const char PrefServiceHashStoreContents::kStoreVersionsDict[] =
+ "store_versions";
+
+PrefServiceHashStoreContents::PrefServiceHashStoreContents(
+ const std::string& hash_store_id,
+ PrefService* pref_service)
+ : hash_store_id_(hash_store_id), pref_service_(pref_service) {
+ // TODO(erikwright): Remove in M40+.
+ DictionaryPrefUpdate update(pref_service_, kProfilePreferenceHashes);
+ update->RemovePath(kStoreVersionsDict, NULL);
+}
+
+// static
+void PrefServiceHashStoreContents::RegisterPrefs(PrefRegistrySimple* registry) {
+ // Register the top level dictionary to map profile names to dictionaries of
+ // tracked preferences.
+ registry->RegisterDictionaryPref(kProfilePreferenceHashes);
+}
+
+// static
+void PrefServiceHashStoreContents::ResetAllPrefHashStores(
+ PrefService* pref_service) {
+ pref_service->ClearPref(kProfilePreferenceHashes);
+}
+
+std::string PrefServiceHashStoreContents::hash_store_id() const {
+ return hash_store_id_;
+}
+
+void PrefServiceHashStoreContents::Reset() {
+ DictionaryPrefUpdate update(pref_service_, kProfilePreferenceHashes);
+
+ update->RemoveWithoutPathExpansion(hash_store_id_, NULL);
+
+ // Remove this store's entry in the kHashOfHashesDict.
+ base::DictionaryValue* hash_of_hashes_dict;
+ if (update->GetDictionaryWithoutPathExpansion(kHashOfHashesDict,
+ &hash_of_hashes_dict)) {
+ hash_of_hashes_dict->RemoveWithoutPathExpansion(hash_store_id_, NULL);
+ if (hash_of_hashes_dict->empty())
+ update->RemovePath(kHashOfHashesDict, NULL);
+ }
+
+ if (update->empty())
+ pref_service_->ClearPref(kProfilePreferenceHashes);
+}
+
+bool PrefServiceHashStoreContents::IsInitialized() const {
+ const base::DictionaryValue* pref_hash_dicts =
+ pref_service_->GetDictionary(kProfilePreferenceHashes);
+ return pref_hash_dicts->GetDictionaryWithoutPathExpansion(hash_store_id_,
+ NULL);
+}
+
+const base::DictionaryValue* PrefServiceHashStoreContents::GetContents() const {
+ const base::DictionaryValue* pref_hash_dicts =
+ pref_service_->GetDictionary(kProfilePreferenceHashes);
+ const base::DictionaryValue* hashes_dict = NULL;
+ pref_hash_dicts->GetDictionaryWithoutPathExpansion(hash_store_id_,
+ &hashes_dict);
+ return hashes_dict;
+}
+
+scoped_ptr<HashStoreContents::MutableDictionary>
+PrefServiceHashStoreContents::GetMutableContents() {
+ return scoped_ptr<HashStoreContents::MutableDictionary>(
+ new PrefServiceMutableDictionary(hash_store_id_, pref_service_));
+}
+
+std::string PrefServiceHashStoreContents::GetSuperMac() const {
+ const base::DictionaryValue* pref_hash_dicts =
+ pref_service_->GetDictionary(kProfilePreferenceHashes);
+ const base::DictionaryValue* hash_of_hashes_dict = NULL;
+ std::string hash_of_hashes;
+ if (pref_hash_dicts->GetDictionaryWithoutPathExpansion(
+ kHashOfHashesDict, &hash_of_hashes_dict)) {
+ hash_of_hashes_dict->GetStringWithoutPathExpansion(hash_store_id_,
+ &hash_of_hashes);
+ }
+ return hash_of_hashes;
+}
+
+void PrefServiceHashStoreContents::SetSuperMac(const std::string& super_mac) {
+ PrefServiceMutableDictionary(kHashOfHashesDict, pref_service_)
+ ->SetStringWithoutPathExpansion(hash_store_id_, super_mac);
+}
diff --git a/chromium/components/user_prefs/tracked/pref_service_hash_store_contents.h b/chromium/components/user_prefs/tracked/pref_service_hash_store_contents.h
new file mode 100644
index 00000000000..2b944e575b0
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_service_hash_store_contents.h
@@ -0,0 +1,72 @@
+// 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_USER_PREFS_TRACKED_PREF_SERVICE_HASH_STORE_CONTENTS_H_
+#define COMPONENTS_USER_PREFS_TRACKED_PREF_SERVICE_HASH_STORE_CONTENTS_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "components/user_prefs/tracked/hash_store_contents.h"
+
+class PrefRegistrySimple;
+class PrefService;
+
+// Implements HashStoreContents by storing hashes in a PrefService. Multiple
+// separate hash stores may coexist in the PrefService by using distinct hash
+// store IDs.
+// TODO(erikwright): This class is only used to recreate preference state as in
+// M35, to test migration behaviour. Remove this class when
+// ProfilePrefStoreManagerTest no longer depends on it.
+class PrefServiceHashStoreContents : public HashStoreContents {
+ public:
+ // Constructs a HashStoreContents that stores hashes in |pref_service|.
+ // Multiple hash stores can use the same |pref_service| with distinct
+ // |hash_store_id|s.
+ //
+ // |pref_service| must have previously been configured using |RegisterPrefs|.
+ PrefServiceHashStoreContents(const std::string& hash_store_id,
+ PrefService* pref_service);
+
+ // A dictionary pref which maps profile names to dictionary values which hold
+ // hashes of profile prefs that we track to detect changes that happen outside
+ // of Chrome.
+ static const char kProfilePreferenceHashes[];
+
+ // The name of a dict that is stored as a child of
+ // |prefs::kProfilePreferenceHashes|. Each child node is a string whose name
+ // is a hash store ID and whose value is the super MAC for the corresponding
+ // hash store.
+ static const char kHashOfHashesDict[];
+
+ // The name of a dict that is stored as a child of
+ // |prefs::kProfilePreferenceHashes|. Each child node is a number whose name
+ // is a hash store ID and whose value is the version of the corresponding
+ // hash store.
+ static const char kStoreVersionsDict[];
+
+ // Registers required preferences.
+ static void RegisterPrefs(PrefRegistrySimple* registry);
+
+ // Deletes stored hashes for all profiles from |pref_service|.
+ static void ResetAllPrefHashStores(PrefService* pref_service);
+
+ // HashStoreContents implementation
+ std::string hash_store_id() const override;
+ void Reset() override;
+ bool IsInitialized() const override;
+ const base::DictionaryValue* GetContents() const override;
+ scoped_ptr<MutableDictionary> GetMutableContents() override;
+ std::string GetSuperMac() const override;
+ void SetSuperMac(const std::string& super_mac) override;
+
+ private:
+ const std::string hash_store_id_;
+ PrefService* pref_service_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefServiceHashStoreContents);
+};
+
+#endif // COMPONENTS_PREFS_TRACKED_PREF_SERVICE_HASH_STORE_CONTENTS_H_
diff --git a/chromium/components/user_prefs/tracked/pref_service_hash_store_contents_unittest.cc b/chromium/components/user_prefs/tracked/pref_service_hash_store_contents_unittest.cc
new file mode 100644
index 00000000000..09003d9ecdd
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/pref_service_hash_store_contents_unittest.cc
@@ -0,0 +1,152 @@
+// 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/user_prefs/tracked/pref_service_hash_store_contents.h"
+
+#include <string>
+
+#include "base/prefs/pref_service.h"
+#include "base/prefs/testing_pref_service.h"
+#include "base/values.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class PrefServiceHashStoreContentsTest : public testing::Test {
+ public:
+ void SetUp() override {
+ PrefServiceHashStoreContents::RegisterPrefs(local_state_.registry());
+ }
+
+ protected:
+ TestingPrefServiceSimple local_state_;
+};
+
+TEST_F(PrefServiceHashStoreContentsTest, hash_store_id) {
+ PrefServiceHashStoreContents contents("store_id", &local_state_);
+ ASSERT_EQ("store_id", contents.hash_store_id());
+}
+
+TEST_F(PrefServiceHashStoreContentsTest, IsInitialized) {
+ {
+ PrefServiceHashStoreContents contents("store_id", &local_state_);
+ ASSERT_FALSE(contents.IsInitialized());
+ (*contents.GetMutableContents())->Set("foo", new base::StringValue("bar"));
+ ASSERT_TRUE(contents.IsInitialized());
+ }
+ {
+ PrefServiceHashStoreContents contents("store_id", &local_state_);
+ ASSERT_TRUE(contents.IsInitialized());
+ PrefServiceHashStoreContents other_contents("other_store_id",
+ &local_state_);
+ ASSERT_FALSE(other_contents.IsInitialized());
+ }
+}
+
+TEST_F(PrefServiceHashStoreContentsTest, Reset) {
+ ASSERT_FALSE(local_state_.GetUserPrefValue(
+ PrefServiceHashStoreContents::kProfilePreferenceHashes));
+
+ {
+ PrefServiceHashStoreContents contents("store_id", &local_state_);
+ ASSERT_FALSE(contents.IsInitialized());
+ (*contents.GetMutableContents())->Set("foo", new base::StringValue("bar"));
+ ASSERT_TRUE(contents.IsInitialized());
+ PrefServiceHashStoreContents other_contents("other_store_id",
+ &local_state_);
+ (*other_contents.GetMutableContents())
+ ->Set("foo", new base::StringValue("bar"));
+ }
+
+ ASSERT_TRUE(local_state_.GetUserPrefValue(
+ PrefServiceHashStoreContents::kProfilePreferenceHashes));
+
+ {
+ PrefServiceHashStoreContents contents("store_id", &local_state_);
+ ASSERT_TRUE(contents.IsInitialized());
+ contents.Reset();
+ ASSERT_FALSE(contents.IsInitialized());
+ }
+
+ ASSERT_TRUE(local_state_.GetUserPrefValue(
+ PrefServiceHashStoreContents::kProfilePreferenceHashes));
+
+ {
+ PrefServiceHashStoreContents contents("store_id", &local_state_);
+ ASSERT_FALSE(contents.IsInitialized());
+ PrefServiceHashStoreContents other_contents("other_store_id",
+ &local_state_);
+ ASSERT_TRUE(other_contents.IsInitialized());
+ }
+
+ {
+ PrefServiceHashStoreContents other_contents("other_store_id",
+ &local_state_);
+ other_contents.Reset();
+ }
+
+ ASSERT_FALSE(local_state_.GetUserPrefValue(
+ PrefServiceHashStoreContents::kProfilePreferenceHashes));
+}
+
+TEST_F(PrefServiceHashStoreContentsTest, GetAndSetContents) {
+ {
+ PrefServiceHashStoreContents contents("store_id", &local_state_);
+ ASSERT_EQ(NULL, contents.GetContents());
+ (*contents.GetMutableContents())->Set("foo", new base::StringValue("bar"));
+ ASSERT_FALSE(contents.GetContents() == NULL);
+ std::string actual_value;
+ ASSERT_TRUE(contents.GetContents()->GetString("foo", &actual_value));
+ ASSERT_EQ("bar", actual_value);
+ PrefServiceHashStoreContents other_contents("other_store_id",
+ &local_state_);
+ ASSERT_EQ(NULL, other_contents.GetContents());
+ }
+ {
+ PrefServiceHashStoreContents contents("store_id", &local_state_);
+ ASSERT_FALSE(contents.GetContents() == NULL);
+ }
+}
+
+TEST_F(PrefServiceHashStoreContentsTest, GetAndSetSuperMac) {
+ {
+ PrefServiceHashStoreContents contents("store_id", &local_state_);
+ ASSERT_TRUE(contents.GetSuperMac().empty());
+ (*contents.GetMutableContents())->Set("foo", new base::StringValue("bar"));
+ ASSERT_TRUE(contents.GetSuperMac().empty());
+ contents.SetSuperMac("0123456789");
+ ASSERT_EQ("0123456789", contents.GetSuperMac());
+ }
+ {
+ PrefServiceHashStoreContents contents("store_id", &local_state_);
+ ASSERT_EQ("0123456789", contents.GetSuperMac());
+ PrefServiceHashStoreContents other_contents("other_store_id",
+ &local_state_);
+ ASSERT_TRUE(other_contents.GetSuperMac().empty());
+ }
+}
+
+TEST_F(PrefServiceHashStoreContentsTest, ResetAllPrefHashStores) {
+ {
+ PrefServiceHashStoreContents contents_1("store_id_1", &local_state_);
+ PrefServiceHashStoreContents contents_2("store_id_2", &local_state_);
+ (*contents_1.GetMutableContents())
+ ->Set("foo", new base::StringValue("bar"));
+ (*contents_2.GetMutableContents())
+ ->Set("foo", new base::StringValue("bar"));
+ }
+ {
+ PrefServiceHashStoreContents contents_1("store_id_1", &local_state_);
+ PrefServiceHashStoreContents contents_2("store_id_2", &local_state_);
+ ASSERT_TRUE(contents_1.IsInitialized());
+ ASSERT_TRUE(contents_2.IsInitialized());
+ }
+
+ PrefServiceHashStoreContents::ResetAllPrefHashStores(&local_state_);
+
+ {
+ PrefServiceHashStoreContents contents_1("store_id_1", &local_state_);
+ PrefServiceHashStoreContents contents_2("store_id_2", &local_state_);
+ ASSERT_FALSE(contents_1.IsInitialized());
+ ASSERT_FALSE(contents_2.IsInitialized());
+ }
+}
diff --git a/chromium/components/user_prefs/tracked/segregated_pref_store.cc b/chromium/components/user_prefs/tracked/segregated_pref_store.cc
new file mode 100644
index 00000000000..99031a2f0ec
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/segregated_pref_store.cc
@@ -0,0 +1,173 @@
+// 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/user_prefs/tracked/segregated_pref_store.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+
+SegregatedPrefStore::AggregatingObserver::AggregatingObserver(
+ SegregatedPrefStore* outer)
+ : outer_(outer),
+ failed_sub_initializations_(0),
+ successful_sub_initializations_(0) {
+}
+
+void SegregatedPrefStore::AggregatingObserver::OnPrefValueChanged(
+ const std::string& key) {
+ // There is no need to tell clients about changes if they have not yet been
+ // told about initialization.
+ if (failed_sub_initializations_ + successful_sub_initializations_ < 2)
+ return;
+
+ FOR_EACH_OBSERVER(PrefStore::Observer, outer_->observers_,
+ OnPrefValueChanged(key));
+}
+
+void SegregatedPrefStore::AggregatingObserver::OnInitializationCompleted(
+ bool succeeded) {
+ if (succeeded)
+ ++successful_sub_initializations_;
+ else
+ ++failed_sub_initializations_;
+
+ DCHECK_LE(failed_sub_initializations_ + successful_sub_initializations_, 2);
+
+ if (failed_sub_initializations_ + successful_sub_initializations_ == 2) {
+ if (successful_sub_initializations_ == 2 && outer_->read_error_delegate_) {
+ PersistentPrefStore::PrefReadError read_error = outer_->GetReadError();
+ if (read_error != PersistentPrefStore::PREF_READ_ERROR_NONE)
+ outer_->read_error_delegate_->OnError(read_error);
+ }
+
+ FOR_EACH_OBSERVER(
+ PrefStore::Observer, outer_->observers_,
+ OnInitializationCompleted(successful_sub_initializations_ == 2));
+ }
+}
+
+SegregatedPrefStore::SegregatedPrefStore(
+ const scoped_refptr<PersistentPrefStore>& default_pref_store,
+ const scoped_refptr<PersistentPrefStore>& selected_pref_store,
+ const std::set<std::string>& selected_pref_names)
+ : default_pref_store_(default_pref_store),
+ selected_pref_store_(selected_pref_store),
+ selected_preference_names_(selected_pref_names),
+ aggregating_observer_(this) {
+ default_pref_store_->AddObserver(&aggregating_observer_);
+ selected_pref_store_->AddObserver(&aggregating_observer_);
+}
+
+void SegregatedPrefStore::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void SegregatedPrefStore::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+bool SegregatedPrefStore::HasObservers() const {
+ return observers_.might_have_observers();
+}
+
+bool SegregatedPrefStore::IsInitializationComplete() const {
+ return default_pref_store_->IsInitializationComplete() &&
+ selected_pref_store_->IsInitializationComplete();
+}
+
+bool SegregatedPrefStore::GetValue(const std::string& key,
+ const base::Value** result) const {
+ return StoreForKey(key)->GetValue(key, result);
+}
+
+void SegregatedPrefStore::SetValue(const std::string& key,
+ scoped_ptr<base::Value> value,
+ uint32 flags) {
+ StoreForKey(key)->SetValue(key, value.Pass(), flags);
+}
+
+void SegregatedPrefStore::RemoveValue(const std::string& key, uint32 flags) {
+ StoreForKey(key)->RemoveValue(key, flags);
+}
+
+bool SegregatedPrefStore::GetMutableValue(const std::string& key,
+ base::Value** result) {
+ return StoreForKey(key)->GetMutableValue(key, result);
+}
+
+void SegregatedPrefStore::ReportValueChanged(const std::string& key,
+ uint32 flags) {
+ StoreForKey(key)->ReportValueChanged(key, flags);
+}
+
+void SegregatedPrefStore::SetValueSilently(const std::string& key,
+ scoped_ptr<base::Value> value,
+ uint32 flags) {
+ StoreForKey(key)->SetValueSilently(key, value.Pass(), flags);
+}
+
+bool SegregatedPrefStore::ReadOnly() const {
+ return selected_pref_store_->ReadOnly() || default_pref_store_->ReadOnly();
+}
+
+PersistentPrefStore::PrefReadError SegregatedPrefStore::GetReadError() const {
+ PersistentPrefStore::PrefReadError read_error =
+ default_pref_store_->GetReadError();
+ if (read_error == PersistentPrefStore::PREF_READ_ERROR_NONE) {
+ read_error = selected_pref_store_->GetReadError();
+ // Ignore NO_FILE from selected_pref_store_.
+ if (read_error == PersistentPrefStore::PREF_READ_ERROR_NO_FILE)
+ read_error = PersistentPrefStore::PREF_READ_ERROR_NONE;
+ }
+ return read_error;
+}
+
+PersistentPrefStore::PrefReadError SegregatedPrefStore::ReadPrefs() {
+ // Note: Both of these stores own PrefFilters which makes ReadPrefs
+ // asynchronous. This is okay in this case as only the first call will be
+ // truly asynchronous, the second call will then unblock the migration in
+ // TrackedPreferencesMigrator and complete synchronously.
+ default_pref_store_->ReadPrefs();
+ PersistentPrefStore::PrefReadError selected_store_read_error =
+ selected_pref_store_->ReadPrefs();
+ DCHECK_NE(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE,
+ selected_store_read_error);
+
+ return GetReadError();
+}
+
+void SegregatedPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
+ read_error_delegate_.reset(error_delegate);
+ default_pref_store_->ReadPrefsAsync(NULL);
+ selected_pref_store_->ReadPrefsAsync(NULL);
+}
+
+void SegregatedPrefStore::CommitPendingWrite() {
+ default_pref_store_->CommitPendingWrite();
+ selected_pref_store_->CommitPendingWrite();
+}
+
+void SegregatedPrefStore::SchedulePendingLossyWrites() {
+ default_pref_store_->SchedulePendingLossyWrites();
+ selected_pref_store_->SchedulePendingLossyWrites();
+}
+
+SegregatedPrefStore::~SegregatedPrefStore() {
+ default_pref_store_->RemoveObserver(&aggregating_observer_);
+ selected_pref_store_->RemoveObserver(&aggregating_observer_);
+}
+
+PersistentPrefStore* SegregatedPrefStore::StoreForKey(const std::string& key) {
+ return (ContainsKey(selected_preference_names_, key)
+ ? selected_pref_store_
+ : default_pref_store_).get();
+}
+
+const PersistentPrefStore* SegregatedPrefStore::StoreForKey(
+ const std::string& key) const {
+ return (ContainsKey(selected_preference_names_, key)
+ ? selected_pref_store_
+ : default_pref_store_).get();
+}
diff --git a/chromium/components/user_prefs/tracked/segregated_pref_store.h b/chromium/components/user_prefs/tracked/segregated_pref_store.h
new file mode 100644
index 00000000000..d2bf013a3be
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/segregated_pref_store.h
@@ -0,0 +1,110 @@
+// 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_USER_PREFS_TRACKED_SEGREGATED_PREF_STORE_H_
+#define COMPONENTS_USER_PREFS_TRACKED_SEGREGATED_PREF_STORE_H_
+
+#include <set>
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
+#include "base/prefs/persistent_pref_store.h"
+
+// Provides a unified PersistentPrefStore implementation that splits its storage
+// and retrieval between two underlying PersistentPrefStore instances: a set of
+// preference names is used to partition the preferences.
+//
+// Combines properties of the two stores as follows:
+// * The unified read error will be:
+// Selected Store Error
+// Default Store Error | NO_ERROR | NO_FILE | other selected |
+// NO_ERROR | NO_ERROR | NO_ERROR | other selected |
+// NO_FILE | NO_FILE | NO_FILE | NO_FILE |
+// other default | other default | other default | other default |
+// * The unified initialization success, initialization completion, and
+// read-only state are the boolean OR of the underlying stores' properties.
+class SegregatedPrefStore : public PersistentPrefStore {
+ public:
+ // Creates an instance that delegates to |selected_pref_store| for the
+ // preferences named in |selected_pref_names| and to |default_pref_store|
+ // for all others. If an unselected preference is present in
+ // |selected_pref_store| (i.e. because it was previously selected) it will
+ // be migrated back to |default_pref_store| upon access via a non-const
+ // method.
+ // |on_initialization| will be invoked when both stores have been initialized,
+ // before observers of the SegregatedPrefStore store are notified.
+ SegregatedPrefStore(
+ const scoped_refptr<PersistentPrefStore>& default_pref_store,
+ const scoped_refptr<PersistentPrefStore>& selected_pref_store,
+ const std::set<std::string>& selected_pref_names);
+
+ // PrefStore implementation
+ void AddObserver(Observer* observer) override;
+ void RemoveObserver(Observer* observer) override;
+ bool HasObservers() const override;
+ bool IsInitializationComplete() const override;
+ bool GetValue(const std::string& key,
+ const base::Value** result) const override;
+
+ // WriteablePrefStore implementation
+ void SetValue(const std::string& key,
+ scoped_ptr<base::Value> value,
+ uint32 flags) override;
+ void RemoveValue(const std::string& key, uint32 flags) override;
+
+ // PersistentPrefStore implementation
+ bool GetMutableValue(const std::string& key, base::Value** result) override;
+ void ReportValueChanged(const std::string& key, uint32 flags) override;
+ void SetValueSilently(const std::string& key,
+ scoped_ptr<base::Value> value,
+ uint32 flags) override;
+ bool ReadOnly() const override;
+ PrefReadError GetReadError() const override;
+ PrefReadError ReadPrefs() override;
+ void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override;
+ void CommitPendingWrite() override;
+ void SchedulePendingLossyWrites() override;
+
+ private:
+ // Aggregates events from the underlying stores and synthesizes external
+ // events via |on_initialization|, |read_error_delegate_|, and |observers_|.
+ class AggregatingObserver : public PrefStore::Observer {
+ public:
+ explicit AggregatingObserver(SegregatedPrefStore* outer);
+
+ // PrefStore::Observer implementation
+ void OnPrefValueChanged(const std::string& key) override;
+ void OnInitializationCompleted(bool succeeded) override;
+
+ private:
+ SegregatedPrefStore* outer_;
+ int failed_sub_initializations_;
+ int successful_sub_initializations_;
+
+ DISALLOW_COPY_AND_ASSIGN(AggregatingObserver);
+ };
+
+ ~SegregatedPrefStore() override;
+
+ // Returns |selected_pref_store| if |key| is selected and |default_pref_store|
+ // otherwise.
+ PersistentPrefStore* StoreForKey(const std::string& key);
+ const PersistentPrefStore* StoreForKey(const std::string& key) const;
+
+ scoped_refptr<PersistentPrefStore> default_pref_store_;
+ scoped_refptr<PersistentPrefStore> selected_pref_store_;
+ std::set<std::string> selected_preference_names_;
+
+ scoped_ptr<PersistentPrefStore::ReadErrorDelegate> read_error_delegate_;
+ base::ObserverList<PrefStore::Observer, true> observers_;
+ AggregatingObserver aggregating_observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(SegregatedPrefStore);
+};
+
+#endif // COMPONENTS_PREFS_TRACKED_SEGREGATED_PREF_STORE_H_
diff --git a/chromium/components/user_prefs/tracked/segregated_pref_store_unittest.cc b/chromium/components/user_prefs/tracked/segregated_pref_store_unittest.cc
new file mode 100644
index 00000000000..dc458a5582c
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/segregated_pref_store_unittest.cc
@@ -0,0 +1,273 @@
+// 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/user_prefs/tracked/segregated_pref_store.h"
+
+#include <set>
+#include <string>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/prefs/persistent_pref_store.h"
+#include "base/prefs/pref_store_observer_mock.h"
+#include "base/prefs/testing_pref_store.h"
+#include "base/values.h"
+#include "components/user_prefs/tracked/segregated_pref_store.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char kSelectedPref[] = "selected_pref";
+const char kUnselectedPref[] = "unselected_pref";
+
+const char kValue1[] = "value1";
+const char kValue2[] = "value2";
+
+class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate {
+ public:
+ struct Data {
+ Data(bool invoked_in, PersistentPrefStore::PrefReadError read_error_in)
+ : invoked(invoked_in), read_error(read_error_in) {}
+
+ bool invoked;
+ PersistentPrefStore::PrefReadError read_error;
+ };
+
+ explicit MockReadErrorDelegate(Data* data) : data_(data) {
+ DCHECK(data_);
+ EXPECT_FALSE(data_->invoked);
+ }
+
+ // PersistentPrefStore::ReadErrorDelegate implementation
+ void OnError(PersistentPrefStore::PrefReadError read_error) override {
+ EXPECT_FALSE(data_->invoked);
+ data_->invoked = true;
+ data_->read_error = read_error;
+ }
+
+ private:
+ Data* data_;
+};
+
+} // namespace
+
+class SegregatedPrefStoreTest : public testing::Test {
+ public:
+ SegregatedPrefStoreTest()
+ : read_error_delegate_data_(false,
+ PersistentPrefStore::PREF_READ_ERROR_NONE),
+ read_error_delegate_(
+ new MockReadErrorDelegate(&read_error_delegate_data_)) {}
+
+ void SetUp() override {
+ selected_store_ = new TestingPrefStore;
+ default_store_ = new TestingPrefStore;
+
+ std::set<std::string> selected_pref_names;
+ selected_pref_names.insert(kSelectedPref);
+
+ segregated_store_ = new SegregatedPrefStore(default_store_, selected_store_,
+ selected_pref_names);
+
+ segregated_store_->AddObserver(&observer_);
+ }
+
+ void TearDown() override { segregated_store_->RemoveObserver(&observer_); }
+
+ protected:
+ scoped_ptr<PersistentPrefStore::ReadErrorDelegate> GetReadErrorDelegate() {
+ EXPECT_TRUE(read_error_delegate_);
+ return read_error_delegate_.Pass();
+ }
+
+ PrefStoreObserverMock observer_;
+
+ scoped_refptr<TestingPrefStore> default_store_;
+ scoped_refptr<TestingPrefStore> selected_store_;
+ scoped_refptr<SegregatedPrefStore> segregated_store_;
+
+ MockReadErrorDelegate::Data read_error_delegate_data_;
+
+ private:
+ scoped_ptr<MockReadErrorDelegate> read_error_delegate_;
+};
+
+TEST_F(SegregatedPrefStoreTest, StoreValues) {
+ ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE,
+ segregated_store_->ReadPrefs());
+
+ // Properly stores new values.
+ segregated_store_->SetValue(kSelectedPref,
+ make_scoped_ptr(new base::StringValue(kValue1)),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ segregated_store_->SetValue(kUnselectedPref,
+ make_scoped_ptr(new base::StringValue(kValue2)),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+
+ ASSERT_TRUE(selected_store_->GetValue(kSelectedPref, NULL));
+ ASSERT_FALSE(selected_store_->GetValue(kUnselectedPref, NULL));
+ ASSERT_FALSE(default_store_->GetValue(kSelectedPref, NULL));
+ ASSERT_TRUE(default_store_->GetValue(kUnselectedPref, NULL));
+
+ ASSERT_TRUE(segregated_store_->GetValue(kSelectedPref, NULL));
+ ASSERT_TRUE(segregated_store_->GetValue(kUnselectedPref, NULL));
+
+ ASSERT_FALSE(selected_store_->committed());
+ ASSERT_FALSE(default_store_->committed());
+
+ segregated_store_->CommitPendingWrite();
+
+ ASSERT_TRUE(selected_store_->committed());
+ ASSERT_TRUE(default_store_->committed());
+}
+
+TEST_F(SegregatedPrefStoreTest, ReadValues) {
+ selected_store_->SetValue(kSelectedPref,
+ make_scoped_ptr(new base::StringValue(kValue1)),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ default_store_->SetValue(kUnselectedPref,
+ make_scoped_ptr(new base::StringValue(kValue2)),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+
+ // Works properly with values that are already there.
+ ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE,
+ segregated_store_->ReadPrefs());
+ ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE,
+ segregated_store_->GetReadError());
+
+ ASSERT_TRUE(selected_store_->GetValue(kSelectedPref, NULL));
+ ASSERT_FALSE(selected_store_->GetValue(kUnselectedPref, NULL));
+ ASSERT_FALSE(default_store_->GetValue(kSelectedPref, NULL));
+ ASSERT_TRUE(default_store_->GetValue(kUnselectedPref, NULL));
+
+ ASSERT_TRUE(segregated_store_->GetValue(kSelectedPref, NULL));
+ ASSERT_TRUE(segregated_store_->GetValue(kUnselectedPref, NULL));
+}
+
+TEST_F(SegregatedPrefStoreTest, Observer) {
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE,
+ segregated_store_->ReadPrefs());
+ EXPECT_TRUE(observer_.initialized);
+ EXPECT_TRUE(observer_.initialization_success);
+ EXPECT_TRUE(observer_.changed_keys.empty());
+ segregated_store_->SetValue(kSelectedPref,
+ make_scoped_ptr(new base::StringValue(kValue1)),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ observer_.VerifyAndResetChangedKey(kSelectedPref);
+ segregated_store_->SetValue(kUnselectedPref,
+ make_scoped_ptr(new base::StringValue(kValue2)),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ observer_.VerifyAndResetChangedKey(kUnselectedPref);
+}
+
+TEST_F(SegregatedPrefStoreTest, SelectedPrefReadNoFileError) {
+ // PREF_READ_ERROR_NO_FILE for the selected prefs file is silently converted
+ // to PREF_READ_ERROR_NONE.
+ selected_store_->set_read_error(PersistentPrefStore::PREF_READ_ERROR_NO_FILE);
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE,
+ segregated_store_->ReadPrefs());
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE,
+ segregated_store_->GetReadError());
+}
+
+TEST_F(SegregatedPrefStoreTest, SelectedPrefReadError) {
+ selected_store_->set_read_error(
+ PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED);
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED,
+ segregated_store_->ReadPrefs());
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED,
+ segregated_store_->GetReadError());
+}
+
+TEST_F(SegregatedPrefStoreTest, SelectedPrefReadNoFileErrorAsync) {
+ // PREF_READ_ERROR_NO_FILE for the selected prefs file is silently converted
+ // to PREF_READ_ERROR_NONE.
+ selected_store_->set_read_error(PersistentPrefStore::PREF_READ_ERROR_NO_FILE);
+
+ default_store_->SetBlockAsyncRead(true);
+
+ EXPECT_FALSE(read_error_delegate_data_.invoked);
+
+ segregated_store_->ReadPrefsAsync(GetReadErrorDelegate().release());
+
+ EXPECT_FALSE(read_error_delegate_data_.invoked);
+
+ default_store_->SetBlockAsyncRead(false);
+
+ // ReadErrorDelegate is not invoked for ERROR_NONE.
+ EXPECT_FALSE(read_error_delegate_data_.invoked);
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE,
+ segregated_store_->GetReadError());
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE,
+ segregated_store_->GetReadError());
+}
+
+TEST_F(SegregatedPrefStoreTest, UnselectedPrefReadNoFileError) {
+ default_store_->set_read_error(PersistentPrefStore::PREF_READ_ERROR_NO_FILE);
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
+ segregated_store_->ReadPrefs());
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
+ segregated_store_->GetReadError());
+}
+
+TEST_F(SegregatedPrefStoreTest, UnselectedPrefReadError) {
+ default_store_->set_read_error(
+ PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED);
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED,
+ segregated_store_->ReadPrefs());
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED,
+ segregated_store_->GetReadError());
+}
+
+TEST_F(SegregatedPrefStoreTest, BothPrefReadError) {
+ default_store_->set_read_error(PersistentPrefStore::PREF_READ_ERROR_NO_FILE);
+ selected_store_->set_read_error(
+ PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED);
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
+ segregated_store_->ReadPrefs());
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
+ segregated_store_->GetReadError());
+}
+
+TEST_F(SegregatedPrefStoreTest, BothPrefReadErrorAsync) {
+ default_store_->set_read_error(PersistentPrefStore::PREF_READ_ERROR_NO_FILE);
+ selected_store_->set_read_error(
+ PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED);
+
+ selected_store_->SetBlockAsyncRead(true);
+
+ EXPECT_FALSE(read_error_delegate_data_.invoked);
+
+ segregated_store_->ReadPrefsAsync(GetReadErrorDelegate().release());
+
+ EXPECT_FALSE(read_error_delegate_data_.invoked);
+
+ selected_store_->SetBlockAsyncRead(false);
+
+ EXPECT_TRUE(read_error_delegate_data_.invoked);
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
+ segregated_store_->GetReadError());
+ EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
+ segregated_store_->GetReadError());
+}
+
+TEST_F(SegregatedPrefStoreTest, IsInitializationComplete) {
+ EXPECT_FALSE(segregated_store_->IsInitializationComplete());
+ segregated_store_->ReadPrefs();
+ EXPECT_TRUE(segregated_store_->IsInitializationComplete());
+}
+
+TEST_F(SegregatedPrefStoreTest, IsInitializationCompleteAsync) {
+ selected_store_->SetBlockAsyncRead(true);
+ default_store_->SetBlockAsyncRead(true);
+ EXPECT_FALSE(segregated_store_->IsInitializationComplete());
+ segregated_store_->ReadPrefsAsync(NULL);
+ EXPECT_FALSE(segregated_store_->IsInitializationComplete());
+ selected_store_->SetBlockAsyncRead(false);
+ EXPECT_FALSE(segregated_store_->IsInitializationComplete());
+ default_store_->SetBlockAsyncRead(false);
+ EXPECT_TRUE(segregated_store_->IsInitializationComplete());
+}
diff --git a/chromium/components/user_prefs/tracked/tracked_atomic_preference.cc b/chromium/components/user_prefs/tracked/tracked_atomic_preference.cc
new file mode 100644
index 00000000000..4eb4b6129d2
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_atomic_preference.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/user_prefs/tracked/tracked_atomic_preference.h"
+
+#include "base/values.h"
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+#include "components/user_prefs/tracked/tracked_preference_validation_delegate.h"
+
+TrackedAtomicPreference::TrackedAtomicPreference(
+ const std::string& pref_path,
+ size_t reporting_id,
+ size_t reporting_ids_count,
+ PrefHashFilter::EnforcementLevel enforcement_level,
+ PrefHashFilter::ValueType value_type,
+ TrackedPreferenceValidationDelegate* delegate)
+ : pref_path_(pref_path),
+ helper_(pref_path,
+ reporting_id,
+ reporting_ids_count,
+ enforcement_level,
+ value_type),
+ delegate_(delegate) {
+}
+
+void TrackedAtomicPreference::OnNewValue(
+ const base::Value* value,
+ PrefHashStoreTransaction* transaction) const {
+ transaction->StoreHash(pref_path_, value);
+}
+
+bool TrackedAtomicPreference::EnforceAndReport(
+ base::DictionaryValue* pref_store_contents,
+ PrefHashStoreTransaction* transaction) const {
+ const base::Value* value = NULL;
+ pref_store_contents->Get(pref_path_, &value);
+ PrefHashStoreTransaction::ValueState value_state =
+ transaction->CheckValue(pref_path_, value);
+
+ helper_.ReportValidationResult(value_state);
+
+ TrackedPreferenceHelper::ResetAction reset_action =
+ helper_.GetAction(value_state);
+ if (delegate_) {
+ delegate_->OnAtomicPreferenceValidation(pref_path_, value, value_state,
+ helper_.IsPersonal());
+ }
+ helper_.ReportAction(reset_action);
+
+ bool was_reset = false;
+ if (reset_action == TrackedPreferenceHelper::DO_RESET) {
+ pref_store_contents->RemovePath(pref_path_, NULL);
+ was_reset = true;
+ }
+
+ if (value_state != PrefHashStoreTransaction::UNCHANGED) {
+ // Store the hash for the new value (whether it was reset or not).
+ const base::Value* new_value = NULL;
+ pref_store_contents->Get(pref_path_, &new_value);
+ transaction->StoreHash(pref_path_, new_value);
+ }
+
+ return was_reset;
+}
diff --git a/chromium/components/user_prefs/tracked/tracked_atomic_preference.h b/chromium/components/user_prefs/tracked/tracked_atomic_preference.h
new file mode 100644
index 00000000000..3e183cf3dbd
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_atomic_preference.h
@@ -0,0 +1,44 @@
+// 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_USER_PREFS_TRACKED_ATOMIC_PREFERENCE_H_
+#define COMPONENTS_USER_PREFS_TRACKED_ATOMIC_PREFERENCE_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "components/user_prefs/tracked/pref_hash_filter.h"
+#include "components/user_prefs/tracked/tracked_preference.h"
+#include "components/user_prefs/tracked/tracked_preference_helper.h"
+
+class TrackedPreferenceValidationDelegate;
+
+// A TrackedAtomicPreference is tracked as a whole. A hash is stored for its
+// entire value and it is entirely reset on mismatch. An optional delegate is
+// notified of the status of the preference during enforcement.
+class TrackedAtomicPreference : public TrackedPreference {
+ public:
+ TrackedAtomicPreference(const std::string& pref_path,
+ size_t reporting_id,
+ size_t reporting_ids_count,
+ PrefHashFilter::EnforcementLevel enforcement_level,
+ PrefHashFilter::ValueType value_type,
+ TrackedPreferenceValidationDelegate* delegate);
+
+ // TrackedPreference implementation.
+ void OnNewValue(const base::Value* value,
+ PrefHashStoreTransaction* transaction) const override;
+ bool EnforceAndReport(base::DictionaryValue* pref_store_contents,
+ PrefHashStoreTransaction* transaction) const override;
+
+ private:
+ const std::string pref_path_;
+ const TrackedPreferenceHelper helper_;
+ TrackedPreferenceValidationDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrackedAtomicPreference);
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_ATOMIC_PREFERENCE_H_
diff --git a/chromium/components/user_prefs/tracked/tracked_preference.h b/chromium/components/user_prefs/tracked/tracked_preference.h
new file mode 100644
index 00000000000..4773ac1cd3c
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_preference.h
@@ -0,0 +1,36 @@
+// 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_USER_PREFS_TRACKED_TRACKED_PREFERENCE_H_
+#define COMPONENTS_USER_PREFS_TRACKED_TRACKED_PREFERENCE_H_
+
+class PrefHashStoreTransaction;
+
+namespace base {
+class DictionaryValue;
+class Value;
+}
+
+// A TrackedPreference tracks changes to an individual preference, reporting and
+// reacting to them according to preference-specific and browser-wide policies.
+class TrackedPreference {
+ public:
+ virtual ~TrackedPreference() {}
+
+ // Notifies the underlying TrackedPreference about its new |value| which
+ // can update hashes in the corresponding hash store via |transaction|.
+ virtual void OnNewValue(const base::Value* value,
+ PrefHashStoreTransaction* transaction) const = 0;
+
+ // Verifies that the value of this TrackedPreference in |pref_store_contents|
+ // is valid. Responds to verification failures according to
+ // preference-specific and browser-wide policy and reports results to via UMA.
+ // May use |transaction| to check/modify hashes in the corresponding hash
+ // store.
+ virtual bool EnforceAndReport(
+ base::DictionaryValue* pref_store_contents,
+ PrefHashStoreTransaction* transaction) const = 0;
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_TRACKED_PREFERENCE_H_
diff --git a/chromium/components/user_prefs/tracked/tracked_preference_helper.cc b/chromium/components/user_prefs/tracked/tracked_preference_helper.cc
new file mode 100644
index 00000000000..ade75aea9f4
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_preference_helper.cc
@@ -0,0 +1,118 @@
+// 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/user_prefs/tracked/tracked_preference_helper.h"
+
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+
+TrackedPreferenceHelper::TrackedPreferenceHelper(
+ const std::string& pref_path,
+ size_t reporting_id,
+ size_t reporting_ids_count,
+ PrefHashFilter::EnforcementLevel enforcement_level,
+ PrefHashFilter::ValueType value_type)
+ : pref_path_(pref_path),
+ reporting_id_(reporting_id),
+ reporting_ids_count_(reporting_ids_count),
+ enforce_(enforcement_level == PrefHashFilter::ENFORCE_ON_LOAD),
+ personal_(value_type == PrefHashFilter::VALUE_PERSONAL) {
+}
+
+TrackedPreferenceHelper::ResetAction TrackedPreferenceHelper::GetAction(
+ PrefHashStoreTransaction::ValueState value_state) const {
+ switch (value_state) {
+ case PrefHashStoreTransaction::UNCHANGED:
+ // Desired case, nothing to do.
+ return DONT_RESET;
+ case PrefHashStoreTransaction::CLEARED:
+ // Unfortunate case, but there is nothing we can do.
+ return DONT_RESET;
+ case PrefHashStoreTransaction::TRUSTED_NULL_VALUE: // Falls through.
+ case PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE:
+ // It is okay to seed the hash in this case.
+ return DONT_RESET;
+ case PrefHashStoreTransaction::SECURE_LEGACY:
+ // Accept secure legacy device ID based hashes.
+ return DONT_RESET;
+ case PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE: // Falls through.
+ case PrefHashStoreTransaction::CHANGED:
+ return enforce_ ? DO_RESET : WANTED_RESET;
+ }
+ NOTREACHED() << "Unexpected PrefHashStoreTransaction::ValueState: "
+ << value_state;
+ return DONT_RESET;
+}
+
+bool TrackedPreferenceHelper::IsPersonal() const {
+ return personal_;
+}
+
+void TrackedPreferenceHelper::ReportValidationResult(
+ PrefHashStoreTransaction::ValueState value_state) const {
+ switch (value_state) {
+ case PrefHashStoreTransaction::UNCHANGED:
+ UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceUnchanged",
+ reporting_id_, reporting_ids_count_);
+ return;
+ case PrefHashStoreTransaction::CLEARED:
+ UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceCleared",
+ reporting_id_, reporting_ids_count_);
+ return;
+ case PrefHashStoreTransaction::SECURE_LEGACY:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Settings.TrackedPreferenceMigratedLegacyDeviceId", reporting_id_,
+ reporting_ids_count_);
+ return;
+ case PrefHashStoreTransaction::CHANGED:
+ UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceChanged",
+ reporting_id_, reporting_ids_count_);
+ return;
+ case PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE:
+ UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceInitialized",
+ reporting_id_, reporting_ids_count_);
+ return;
+ case PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE:
+ UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceTrustedInitialized",
+ reporting_id_, reporting_ids_count_);
+ return;
+ case PrefHashStoreTransaction::TRUSTED_NULL_VALUE:
+ UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceNullInitialized",
+ reporting_id_, reporting_ids_count_);
+ return;
+ }
+ NOTREACHED() << "Unexpected PrefHashStoreTransaction::ValueState: "
+ << value_state;
+}
+
+void TrackedPreferenceHelper::ReportAction(ResetAction reset_action) const {
+ switch (reset_action) {
+ case DONT_RESET:
+ // No report for DONT_RESET.
+ break;
+ case WANTED_RESET:
+ UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceWantedReset",
+ reporting_id_, reporting_ids_count_);
+ break;
+ case DO_RESET:
+ UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceReset",
+ reporting_id_, reporting_ids_count_);
+ break;
+ }
+}
+
+void TrackedPreferenceHelper::ReportSplitPreferenceChangedCount(
+ size_t count) const {
+ // The histogram below is an expansion of the UMA_HISTOGRAM_COUNTS_100 macro
+ // adapted to allow for a dynamically suffixed histogram name.
+ // Note: The factory creates and owns the histogram.
+ base::HistogramBase* histogram =
+ base::LinearHistogram::FactoryGet(
+ "Settings.TrackedSplitPreferenceChanged." + pref_path_,
+ 1,
+ 100, // Allow counts up to 100.
+ 101,
+ base::HistogramBase::kUmaTargetedHistogramFlag);
+ histogram->Add(count);
+}
diff --git a/chromium/components/user_prefs/tracked/tracked_preference_helper.h b/chromium/components/user_prefs/tracked/tracked_preference_helper.h
new file mode 100644
index 00000000000..f2fe338d34e
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_preference_helper.h
@@ -0,0 +1,67 @@
+// 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_USER_PREFS_TRACKED_TRACKED_PREFERENCE_HELPER_H_
+#define COMPONENTS_USER_PREFS_TRACKED_TRACKED_PREFERENCE_HELPER_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "components/user_prefs/tracked/pref_hash_filter.h"
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+
+// A TrackedPreferenceHelper is a helper class for TrackedPreference which
+// handles decision making and reporting for TrackedPreference's
+// implementations.
+class TrackedPreferenceHelper {
+ public:
+ enum ResetAction {
+ DONT_RESET,
+ // WANTED_RESET is reported when DO_RESET would have been reported but the
+ // current |enforcement_level| doesn't allow a reset for the detected state.
+ WANTED_RESET,
+ DO_RESET,
+ };
+
+ TrackedPreferenceHelper(const std::string& pref_path,
+ size_t reporting_id,
+ size_t reporting_ids_count,
+ PrefHashFilter::EnforcementLevel enforcement_level,
+ PrefHashFilter::ValueType value_type);
+
+ // Returns a ResetAction stating whether a reset is desired (DO_RESET) or not
+ // (DONT_RESET) based on observing |value_state|. Can also return WANTED_RESET
+ // if a reset would have been desired but the current |enforcement_level|
+ // doesn't allow it.
+ ResetAction GetAction(PrefHashStoreTransaction::ValueState value_state) const;
+
+ // Returns true if the preference value may contain personal information.
+ bool IsPersonal() const;
+
+ // Reports |value_state| via UMA under |reporting_id_|.
+ void ReportValidationResult(
+ PrefHashStoreTransaction::ValueState value_state) const;
+
+ // Reports |reset_action| via UMA under |reporting_id_|.
+ void ReportAction(ResetAction reset_action) const;
+
+ // Reports, via UMA, the |count| of split preference entries that were
+ // considered invalid in a CHANGED event.
+ void ReportSplitPreferenceChangedCount(size_t count) const;
+
+ private:
+ const std::string pref_path_;
+
+ const size_t reporting_id_;
+ const size_t reporting_ids_count_;
+
+ // Deny setting changes and hash seeding/migration.
+ const bool enforce_;
+
+ const bool personal_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrackedPreferenceHelper);
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_TRACKED_PREFERENCE_HELPER_H_
diff --git a/chromium/components/user_prefs/tracked/tracked_preference_validation_delegate.h b/chromium/components/user_prefs/tracked/tracked_preference_validation_delegate.h
new file mode 100644
index 00000000000..8ea9c80a0a5
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_preference_validation_delegate.h
@@ -0,0 +1,44 @@
+// 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_USER_PREFS_TRACKED_TRACKED_PREFERENCE_VALIDATION_DELEGATE_H_
+#define COMPONENTS_USER_PREFS_TRACKED_TRACKED_PREFERENCE_VALIDATION_DELEGATE_H_
+
+#include <string>
+#include <vector>
+
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+
+namespace base {
+class DictionaryValue;
+class Value;
+}
+
+// A TrackedPreferenceValidationDelegate is notified of the results of each
+// tracked preference validation event.
+class TrackedPreferenceValidationDelegate {
+ public:
+ virtual ~TrackedPreferenceValidationDelegate() {}
+
+ // Notifies observes of the result (|value_state|) of checking the atomic
+ // |value| (which may be NULL) at |pref_path|. |is_personal| indicates whether
+ // or not the value may contain personal information.
+ virtual void OnAtomicPreferenceValidation(
+ const std::string& pref_path,
+ const base::Value* value,
+ PrefHashStoreTransaction::ValueState value_state,
+ bool is_personal) = 0;
+
+ // Notifies observes of the result (|value_state|) of checking the split
+ // |dict_value| (which may be NULL) at |pref_path|. |is_personal| indicates
+ // whether or not the value may contain personal information.
+ virtual void OnSplitPreferenceValidation(
+ const std::string& pref_path,
+ const base::DictionaryValue* dict_value,
+ const std::vector<std::string>& invalid_keys,
+ PrefHashStoreTransaction::ValueState value_state,
+ bool is_personal) = 0;
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_TRACKED_PREFERENCE_VALIDATION_DELEGATE_H_
diff --git a/chromium/components/user_prefs/tracked/tracked_preferences_migration.cc b/chromium/components/user_prefs/tracked/tracked_preferences_migration.cc
new file mode 100644
index 00000000000..edcbae512c5
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_preferences_migration.cc
@@ -0,0 +1,370 @@
+// 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/user_prefs/tracked/tracked_preferences_migration.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/metrics/histogram.h"
+#include "base/values.h"
+#include "components/user_prefs/tracked/dictionary_hash_store_contents.h"
+#include "components/user_prefs/tracked/hash_store_contents.h"
+#include "components/user_prefs/tracked/interceptable_pref_filter.h"
+#include "components/user_prefs/tracked/pref_hash_store.h"
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+
+namespace {
+
+class TrackedPreferencesMigrator
+ : public base::RefCounted<TrackedPreferencesMigrator> {
+ public:
+ TrackedPreferencesMigrator(
+ const std::set<std::string>& unprotected_pref_names,
+ const std::set<std::string>& protected_pref_names,
+ const base::Callback<void(const std::string& key)>&
+ unprotected_store_cleaner,
+ const base::Callback<void(const std::string& key)>&
+ protected_store_cleaner,
+ const base::Callback<void(const base::Closure&)>&
+ register_on_successful_unprotected_store_write_callback,
+ const base::Callback<void(const base::Closure&)>&
+ register_on_successful_protected_store_write_callback,
+ scoped_ptr<PrefHashStore> unprotected_pref_hash_store,
+ scoped_ptr<PrefHashStore> protected_pref_hash_store,
+ scoped_ptr<HashStoreContents> legacy_pref_hash_store,
+ InterceptablePrefFilter* unprotected_pref_filter,
+ InterceptablePrefFilter* protected_pref_filter);
+
+ private:
+ friend class base::RefCounted<TrackedPreferencesMigrator>;
+
+ enum PrefFilterID {
+ UNPROTECTED_PREF_FILTER,
+ PROTECTED_PREF_FILTER
+ };
+
+ ~TrackedPreferencesMigrator();
+
+ // Stores the data coming in from the filter identified by |id| into this
+ // class and then calls MigrateIfReady();
+ void InterceptFilterOnLoad(
+ PrefFilterID id,
+ const InterceptablePrefFilter::FinalizeFilterOnLoadCallback&
+ finalize_filter_on_load,
+ scoped_ptr<base::DictionaryValue> prefs);
+
+ // Proceeds with migration if both |unprotected_prefs_| and |protected_prefs_|
+ // have been set.
+ void MigrateIfReady();
+
+ const std::set<std::string> unprotected_pref_names_;
+ const std::set<std::string> protected_pref_names_;
+
+ const base::Callback<void(const std::string& key)> unprotected_store_cleaner_;
+ const base::Callback<void(const std::string& key)> protected_store_cleaner_;
+ const base::Callback<void(const base::Closure&)>
+ register_on_successful_unprotected_store_write_callback_;
+ const base::Callback<void(const base::Closure&)>
+ register_on_successful_protected_store_write_callback_;
+
+ InterceptablePrefFilter::FinalizeFilterOnLoadCallback
+ finalize_unprotected_filter_on_load_;
+ InterceptablePrefFilter::FinalizeFilterOnLoadCallback
+ finalize_protected_filter_on_load_;
+
+ scoped_ptr<PrefHashStore> unprotected_pref_hash_store_;
+ scoped_ptr<PrefHashStore> protected_pref_hash_store_;
+ scoped_ptr<HashStoreContents> legacy_pref_hash_store_;
+
+ scoped_ptr<base::DictionaryValue> unprotected_prefs_;
+ scoped_ptr<base::DictionaryValue> protected_prefs_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrackedPreferencesMigrator);
+};
+
+// Invokes |store_cleaner| for every |keys_to_clean|.
+void CleanupPrefStore(
+ const base::Callback<void(const std::string& key)>& store_cleaner,
+ const std::set<std::string>& keys_to_clean) {
+ for (std::set<std::string>::const_iterator it = keys_to_clean.begin();
+ it != keys_to_clean.end(); ++it) {
+ store_cleaner.Run(*it);
+ }
+}
+
+// If |wait_for_commit_to_destination_store|: schedules (via
+// |register_on_successful_destination_store_write_callback|) a cleanup of the
+// |keys_to_clean| from the source pref store (through |source_store_cleaner|)
+// once the destination pref store they were migrated to was successfully
+// written to disk. Otherwise, executes the cleanup right away.
+void ScheduleSourcePrefStoreCleanup(
+ const base::Callback<void(const base::Closure&)>&
+ register_on_successful_destination_store_write_callback,
+ const base::Callback<void(const std::string& key)>& source_store_cleaner,
+ const std::set<std::string>& keys_to_clean,
+ bool wait_for_commit_to_destination_store) {
+ DCHECK(!keys_to_clean.empty());
+ if (wait_for_commit_to_destination_store) {
+ register_on_successful_destination_store_write_callback.Run(
+ base::Bind(&CleanupPrefStore, source_store_cleaner, keys_to_clean));
+ } else {
+ CleanupPrefStore(source_store_cleaner, keys_to_clean);
+ }
+}
+
+// Removes hashes for |migrated_pref_names| from |origin_pref_store| using
+// the configuration/implementation in |origin_pref_hash_store|.
+void CleanupMigratedHashes(const std::set<std::string>& migrated_pref_names,
+ PrefHashStore* origin_pref_hash_store,
+ base::DictionaryValue* origin_pref_store) {
+ scoped_ptr<PrefHashStoreTransaction> transaction(
+ origin_pref_hash_store->BeginTransaction(scoped_ptr<HashStoreContents>(
+ new DictionaryHashStoreContents(origin_pref_store))));
+ for (std::set<std::string>::const_iterator it = migrated_pref_names.begin();
+ it != migrated_pref_names.end();
+ ++it) {
+ transaction->ClearHash(*it);
+ }
+}
+
+// Copies the value of each pref in |pref_names| which is set in |old_store|,
+// but not in |new_store| into |new_store|. Sets |old_store_needs_cleanup| to
+// true if any old duplicates remain in |old_store| and sets |new_store_altered|
+// to true if any value was copied to |new_store|.
+void MigratePrefsFromOldToNewStore(const std::set<std::string>& pref_names,
+ base::DictionaryValue* old_store,
+ base::DictionaryValue* new_store,
+ PrefHashStore* new_hash_store,
+ HashStoreContents* legacy_hash_store,
+ bool* old_store_needs_cleanup,
+ bool* new_store_altered,
+ bool* used_legacy_pref_hashes) {
+ const base::DictionaryValue* old_hash_store_contents =
+ DictionaryHashStoreContents(old_store).GetContents();
+ const base::DictionaryValue* legacy_hash_store_contents =
+ legacy_hash_store->GetContents();
+ scoped_ptr<PrefHashStoreTransaction> new_hash_store_transaction(
+ new_hash_store->BeginTransaction(scoped_ptr<HashStoreContents>(
+ new DictionaryHashStoreContents(new_store))));
+
+ for (std::set<std::string>::const_iterator it = pref_names.begin();
+ it != pref_names.end();
+ ++it) {
+ const std::string& pref_name = *it;
+ const base::Value* value_in_old_store = NULL;
+
+ // If the destination does not have a hash for this pref we will
+ // unconditionally attempt to move it.
+ bool destination_hash_missing =
+ !new_hash_store_transaction->HasHash(pref_name);
+ // If we migrate the value we will also attempt to migrate the hash.
+ bool migrated_value = false;
+ if (old_store->Get(pref_name, &value_in_old_store)) {
+ // Whether this value ends up being copied below or was left behind by a
+ // previous incomplete migration, it should be cleaned up.
+ *old_store_needs_cleanup = true;
+
+ if (!new_store->Get(pref_name, NULL)) {
+ // Copy the value from |old_store| to |new_store| rather than moving it
+ // to avoid data loss should |old_store| be flushed to disk without
+ // |new_store| having equivalently been successfully flushed to disk
+ // (e.g., on crash or in cases where |new_store| is read-only following
+ // a read error on startup).
+ new_store->Set(pref_name, value_in_old_store->DeepCopy());
+ migrated_value = true;
+ *new_store_altered = true;
+ }
+ }
+
+ if (destination_hash_missing || migrated_value) {
+ const base::Value* old_hash = NULL;
+ if (old_hash_store_contents)
+ old_hash_store_contents->Get(pref_name, &old_hash);
+ if (!old_hash && legacy_hash_store_contents) {
+ legacy_hash_store_contents->Get(pref_name, &old_hash);
+ if (old_hash)
+ *used_legacy_pref_hashes = true;
+ }
+ if (old_hash) {
+ new_hash_store_transaction->ImportHash(pref_name, old_hash);
+ *new_store_altered = true;
+ } else if (!destination_hash_missing) {
+ // Do not allow values to be migrated without MACs if the destination
+ // already has a MAC (http://crbug.com/414554). Remove the migrated
+ // value in order to provide the same no-op behaviour as if the pref was
+ // added to the wrong file when there was already a value for
+ // |pref_name| in |new_store|.
+ new_store->Remove(pref_name, NULL);
+ *new_store_altered = true;
+ }
+ }
+ }
+}
+
+TrackedPreferencesMigrator::TrackedPreferencesMigrator(
+ const std::set<std::string>& unprotected_pref_names,
+ const std::set<std::string>& protected_pref_names,
+ const base::Callback<void(const std::string& key)>&
+ unprotected_store_cleaner,
+ const base::Callback<void(const std::string& key)>& protected_store_cleaner,
+ const base::Callback<void(const base::Closure&)>&
+ register_on_successful_unprotected_store_write_callback,
+ const base::Callback<void(const base::Closure&)>&
+ register_on_successful_protected_store_write_callback,
+ scoped_ptr<PrefHashStore> unprotected_pref_hash_store,
+ scoped_ptr<PrefHashStore> protected_pref_hash_store,
+ scoped_ptr<HashStoreContents> legacy_pref_hash_store,
+ InterceptablePrefFilter* unprotected_pref_filter,
+ InterceptablePrefFilter* protected_pref_filter)
+ : unprotected_pref_names_(unprotected_pref_names),
+ protected_pref_names_(protected_pref_names),
+ unprotected_store_cleaner_(unprotected_store_cleaner),
+ protected_store_cleaner_(protected_store_cleaner),
+ register_on_successful_unprotected_store_write_callback_(
+ register_on_successful_unprotected_store_write_callback),
+ register_on_successful_protected_store_write_callback_(
+ register_on_successful_protected_store_write_callback),
+ unprotected_pref_hash_store_(unprotected_pref_hash_store.Pass()),
+ protected_pref_hash_store_(protected_pref_hash_store.Pass()),
+ legacy_pref_hash_store_(legacy_pref_hash_store.Pass()) {
+ // The callbacks bound below will own this TrackedPreferencesMigrator by
+ // reference.
+ unprotected_pref_filter->InterceptNextFilterOnLoad(
+ base::Bind(&TrackedPreferencesMigrator::InterceptFilterOnLoad,
+ this,
+ UNPROTECTED_PREF_FILTER));
+ protected_pref_filter->InterceptNextFilterOnLoad(
+ base::Bind(&TrackedPreferencesMigrator::InterceptFilterOnLoad,
+ this,
+ PROTECTED_PREF_FILTER));
+}
+
+TrackedPreferencesMigrator::~TrackedPreferencesMigrator() {}
+
+void TrackedPreferencesMigrator::InterceptFilterOnLoad(
+ PrefFilterID id,
+ const InterceptablePrefFilter::FinalizeFilterOnLoadCallback&
+ finalize_filter_on_load,
+ scoped_ptr<base::DictionaryValue> prefs) {
+ switch (id) {
+ case UNPROTECTED_PREF_FILTER:
+ finalize_unprotected_filter_on_load_ = finalize_filter_on_load;
+ unprotected_prefs_ = prefs.Pass();
+ break;
+ case PROTECTED_PREF_FILTER:
+ finalize_protected_filter_on_load_ = finalize_filter_on_load;
+ protected_prefs_ = prefs.Pass();
+ break;
+ }
+
+ MigrateIfReady();
+}
+
+void TrackedPreferencesMigrator::MigrateIfReady() {
+ // Wait for both stores to have been read before proceeding.
+ if (!protected_prefs_ || !unprotected_prefs_)
+ return;
+
+ bool used_legacy_pref_hashes = false;
+ bool protected_prefs_need_cleanup = false;
+ bool unprotected_prefs_altered = false;
+ MigratePrefsFromOldToNewStore(unprotected_pref_names_,
+ protected_prefs_.get(),
+ unprotected_prefs_.get(),
+ unprotected_pref_hash_store_.get(),
+ legacy_pref_hash_store_.get(),
+ &protected_prefs_need_cleanup,
+ &unprotected_prefs_altered,
+ &used_legacy_pref_hashes);
+ bool unprotected_prefs_need_cleanup = false;
+ bool protected_prefs_altered = false;
+ MigratePrefsFromOldToNewStore(protected_pref_names_,
+ unprotected_prefs_.get(),
+ protected_prefs_.get(),
+ protected_pref_hash_store_.get(),
+ legacy_pref_hash_store_.get(),
+ &unprotected_prefs_need_cleanup,
+ &protected_prefs_altered,
+ &used_legacy_pref_hashes);
+ UMA_HISTOGRAM_BOOLEAN("Settings.MigratedHashesFromLocalState",
+ used_legacy_pref_hashes);
+
+ if (!unprotected_prefs_altered && !protected_prefs_altered) {
+ // Clean up any MACs that might have been previously migrated from the
+ // various stores. It's safe to leave them behind for a little while as they
+ // will be ignored unless the corresponding value is _also_ present. The
+ // cleanup must be deferred until the MACs have been written to their target
+ // stores, and doing so in a subsequent launch is easier than within the
+ // same process.
+ CleanupMigratedHashes(unprotected_pref_names_,
+ protected_pref_hash_store_.get(),
+ protected_prefs_.get());
+ CleanupMigratedHashes(protected_pref_names_,
+ unprotected_pref_hash_store_.get(),
+ unprotected_prefs_.get());
+ legacy_pref_hash_store_->Reset();
+ }
+
+ // Hand the processed prefs back to their respective filters.
+ finalize_unprotected_filter_on_load_.Run(unprotected_prefs_.Pass(),
+ unprotected_prefs_altered);
+ finalize_protected_filter_on_load_.Run(protected_prefs_.Pass(),
+ protected_prefs_altered);
+
+ if (unprotected_prefs_need_cleanup) {
+ // Schedule a cleanup of the |protected_pref_names_| from the unprotected
+ // prefs once the protected prefs were successfully written to disk (or
+ // do it immediately if |!protected_prefs_altered|).
+ ScheduleSourcePrefStoreCleanup(
+ register_on_successful_protected_store_write_callback_,
+ unprotected_store_cleaner_,
+ protected_pref_names_,
+ protected_prefs_altered);
+ }
+
+ if (protected_prefs_need_cleanup) {
+ // Schedule a cleanup of the |unprotected_pref_names_| from the protected
+ // prefs once the unprotected prefs were successfully written to disk (or
+ // do it immediately if |!unprotected_prefs_altered|).
+ ScheduleSourcePrefStoreCleanup(
+ register_on_successful_unprotected_store_write_callback_,
+ protected_store_cleaner_,
+ unprotected_pref_names_,
+ unprotected_prefs_altered);
+ }
+}
+
+} // namespace
+
+void SetupTrackedPreferencesMigration(
+ const std::set<std::string>& unprotected_pref_names,
+ const std::set<std::string>& protected_pref_names,
+ const base::Callback<void(const std::string& key)>&
+ unprotected_store_cleaner,
+ const base::Callback<void(const std::string& key)>& protected_store_cleaner,
+ const base::Callback<void(const base::Closure&)>&
+ register_on_successful_unprotected_store_write_callback,
+ const base::Callback<void(const base::Closure&)>&
+ register_on_successful_protected_store_write_callback,
+ scoped_ptr<PrefHashStore> unprotected_pref_hash_store,
+ scoped_ptr<PrefHashStore> protected_pref_hash_store,
+ scoped_ptr<HashStoreContents> legacy_pref_hash_store,
+ InterceptablePrefFilter* unprotected_pref_filter,
+ InterceptablePrefFilter* protected_pref_filter) {
+ scoped_refptr<TrackedPreferencesMigrator> prefs_migrator(
+ new TrackedPreferencesMigrator(
+ unprotected_pref_names,
+ protected_pref_names,
+ unprotected_store_cleaner,
+ protected_store_cleaner,
+ register_on_successful_unprotected_store_write_callback,
+ register_on_successful_protected_store_write_callback,
+ unprotected_pref_hash_store.Pass(),
+ protected_pref_hash_store.Pass(),
+ legacy_pref_hash_store.Pass(),
+ unprotected_pref_filter,
+ protected_pref_filter));
+}
diff --git a/chromium/components/user_prefs/tracked/tracked_preferences_migration.h b/chromium/components/user_prefs/tracked/tracked_preferences_migration.h
new file mode 100644
index 00000000000..fecc0022657
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_preferences_migration.h
@@ -0,0 +1,48 @@
+// 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_USER_PREFS_TRACKED_TRACKED_PREFERENCES_MIGRATION_H_
+#define COMPONENTS_USER_PREFS_TRACKED_TRACKED_PREFERENCES_MIGRATION_H_
+
+#include <set>
+#include <string>
+
+#include "base/callback_forward.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/user_prefs/tracked/pref_hash_store.h"
+
+class HashStoreContents;
+class InterceptablePrefFilter;
+class PrefHashStore;
+
+// Sets up InterceptablePrefFilter::FilterOnLoadInterceptors on
+// |unprotected_pref_filter| and |protected_pref_filter| which prevents each
+// filter from running their on load operations until the interceptors decide to
+// hand the prefs back to them (after migration is complete). |
+// (un)protected_store_cleaner| and
+// |register_on_successful_(un)protected_store_write_callback| are used to do
+// post-migration cleanup tasks. Those should be bound to weak pointers to avoid
+// blocking shutdown. |(un)protected_pref_hash_store| and
+// |legacy_pref_hash_store| are used to migrate MACs along with their protected
+// preferences and/or from the legacy location in Local State. Migrated MACs
+// will only be cleared from their old location in a subsequent run. The
+// migration framework is resilient to a failed cleanup (it will simply try
+// again in the next Chrome run).
+void SetupTrackedPreferencesMigration(
+ const std::set<std::string>& unprotected_pref_names,
+ const std::set<std::string>& protected_pref_names,
+ const base::Callback<void(const std::string& key)>&
+ unprotected_store_cleaner,
+ const base::Callback<void(const std::string& key)>& protected_store_cleaner,
+ const base::Callback<void(const base::Closure&)>&
+ register_on_successful_unprotected_store_write_callback,
+ const base::Callback<void(const base::Closure&)>&
+ register_on_successful_protected_store_write_callback,
+ scoped_ptr<PrefHashStore> unprotected_pref_hash_store,
+ scoped_ptr<PrefHashStore> protected_pref_hash_store,
+ scoped_ptr<HashStoreContents> legacy_pref_hash_store,
+ InterceptablePrefFilter* unprotected_pref_filter,
+ InterceptablePrefFilter* protected_pref_filter);
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_TRACKED_PREFERENCES_MIGRATION_H_
diff --git a/chromium/components/user_prefs/tracked/tracked_preferences_migration_unittest.cc b/chromium/components/user_prefs/tracked/tracked_preferences_migration_unittest.cc
new file mode 100644
index 00000000000..ed44bbad4e2
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_preferences_migration_unittest.cc
@@ -0,0 +1,905 @@
+// 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/user_prefs/tracked/tracked_preferences_migration.h"
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/prefs/testing_pref_service.h"
+#include "base/strings/string_split.h"
+#include "base/values.h"
+#include "components/user_prefs/tracked/dictionary_hash_store_contents.h"
+#include "components/user_prefs/tracked/hash_store_contents.h"
+#include "components/user_prefs/tracked/interceptable_pref_filter.h"
+#include "components/user_prefs/tracked/pref_hash_store.h"
+#include "components/user_prefs/tracked/pref_hash_store_impl.h"
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+#include "components/user_prefs/tracked/pref_service_hash_store_contents.h"
+#include "components/user_prefs/tracked/tracked_preferences_migration.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+// An unprotected pref.
+const char kUnprotectedPref[] = "unprotected";
+// A protected pref.
+const char kProtectedPref[] = "protected";
+// A protected pref which is initially stored in the unprotected store.
+const char kPreviouslyUnprotectedPref[] = "previously.unprotected";
+// An unprotected pref which is initially stored in the protected store.
+const char kPreviouslyProtectedPref[] = "previously.protected";
+
+const char kUnprotectedPrefValue[] = "unprotected_value";
+const char kProtectedPrefValue[] = "protected_value";
+const char kPreviouslyUnprotectedPrefValue[] = "previously_unprotected_value";
+const char kPreviouslyProtectedPrefValue[] = "previously_protected_value";
+
+// A simple InterceptablePrefFilter which doesn't do anything but hand the prefs
+// back downstream in FinalizeFilterOnLoad.
+class SimpleInterceptablePrefFilter : public InterceptablePrefFilter {
+ public:
+ // PrefFilter remaining implementation.
+ void FilterUpdate(const std::string& path) override { ADD_FAILURE(); }
+ void FilterSerializeData(
+ base::DictionaryValue* pref_store_contents) override {
+ ADD_FAILURE();
+ }
+
+ private:
+ // InterceptablePrefFilter implementation.
+ void FinalizeFilterOnLoad(
+ const PostFilterOnLoadCallback& post_filter_on_load_callback,
+ scoped_ptr<base::DictionaryValue> pref_store_contents,
+ bool prefs_altered) override {
+ post_filter_on_load_callback.Run(pref_store_contents.Pass(), prefs_altered);
+ }
+};
+
+// A test fixture designed to be used like this:
+// 1) Set up initial store prefs with PresetStoreValue().
+// 2) Hand both sets of prefs to the migrator via HandPrefsToMigrator().
+// 3) Migration completes synchronously when the second store hands its prefs
+// over.
+// 4) Verifications can be made via various methods of this fixture.
+// Call Reset() to perform a second migration.
+class TrackedPreferencesMigrationTest : public testing::Test {
+ public:
+ enum MockPrefStoreID {
+ MOCK_UNPROTECTED_PREF_STORE,
+ MOCK_PROTECTED_PREF_STORE,
+ };
+
+ TrackedPreferencesMigrationTest()
+ : unprotected_prefs_(new base::DictionaryValue),
+ protected_prefs_(new base::DictionaryValue),
+ migration_modified_unprotected_store_(false),
+ migration_modified_protected_store_(false),
+ unprotected_store_migration_complete_(false),
+ protected_store_migration_complete_(false) {}
+
+ void SetUp() override {
+ PrefServiceHashStoreContents::RegisterPrefs(local_state_.registry());
+ Reset();
+ }
+
+ void Reset() {
+ std::set<std::string> unprotected_pref_names;
+ std::set<std::string> protected_pref_names;
+ unprotected_pref_names.insert(kUnprotectedPref);
+ unprotected_pref_names.insert(kPreviouslyProtectedPref);
+ protected_pref_names.insert(kProtectedPref);
+ protected_pref_names.insert(kPreviouslyUnprotectedPref);
+
+ migration_modified_unprotected_store_ = false;
+ migration_modified_protected_store_ = false;
+ unprotected_store_migration_complete_ = false;
+ protected_store_migration_complete_ = false;
+
+ unprotected_store_successful_write_callback_.Reset();
+ protected_store_successful_write_callback_.Reset();
+
+ SetupTrackedPreferencesMigration(
+ unprotected_pref_names,
+ protected_pref_names,
+ base::Bind(&TrackedPreferencesMigrationTest::RemovePathFromStore,
+ base::Unretained(this),
+ MOCK_UNPROTECTED_PREF_STORE),
+ base::Bind(&TrackedPreferencesMigrationTest::RemovePathFromStore,
+ base::Unretained(this),
+ MOCK_PROTECTED_PREF_STORE),
+ base::Bind(
+ &TrackedPreferencesMigrationTest::RegisterSuccessfulWriteClosure,
+ base::Unretained(this),
+ MOCK_UNPROTECTED_PREF_STORE),
+ base::Bind(
+ &TrackedPreferencesMigrationTest::RegisterSuccessfulWriteClosure,
+ base::Unretained(this),
+ MOCK_PROTECTED_PREF_STORE),
+ scoped_ptr<PrefHashStore>(
+ new PrefHashStoreImpl(kSeed, kDeviceId, false)),
+ scoped_ptr<PrefHashStore>(
+ new PrefHashStoreImpl(kSeed, kDeviceId, true)),
+ scoped_ptr<HashStoreContents>(
+ new PrefServiceHashStoreContents(kHashStoreId, &local_state_)),
+
+ &mock_unprotected_pref_filter_,
+ &mock_protected_pref_filter_);
+
+ // Verify initial expectations are met.
+ EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_FALSE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_FALSE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
+ }
+
+ protected:
+ // Sets |key| to |value| in the test store identified by |store_id| before
+ // migration begins. Also sets the corresponding hash in the same store.
+ void PresetStoreValue(MockPrefStoreID store_id,
+ const std::string& key,
+ const std::string value) {
+ PresetStoreValueOnly(store_id, key, value);
+ PresetStoreValueHash(store_id, key, value);
+ }
+
+ // Sets |key| to |value| in the test store identified by |store_id| before
+ // migration begins. Stores the value hash in Local State as in M36 and
+ // earlier.
+ void PresetLegacyStoreValue(MockPrefStoreID store_id,
+ const std::string& key,
+ const std::string value) {
+ PresetStoreValueOnly(store_id, key, value);
+ PresetLegacyValueHash(key, value);
+ }
+
+ // Stores a hash for |key| and |value| in the hash store identified by
+ // |store_id| before migration begins.
+ void PresetStoreValueHash(MockPrefStoreID store_id,
+ const std::string& key,
+ const std::string value) {
+ base::DictionaryValue* store = NULL;
+ scoped_ptr<PrefHashStore> pref_hash_store;
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ store = unprotected_prefs_.get();
+ pref_hash_store.reset(new PrefHashStoreImpl(kSeed, kDeviceId, false));
+ break;
+ case MOCK_PROTECTED_PREF_STORE:
+ store = protected_prefs_.get();
+ pref_hash_store.reset(new PrefHashStoreImpl(kSeed, kDeviceId, true));
+ break;
+ }
+ DCHECK(store);
+
+ base::StringValue string_value(value);
+ pref_hash_store->BeginTransaction(
+ scoped_ptr<HashStoreContents>(
+ new DictionaryHashStoreContents(store)))->StoreHash(
+ key, &string_value);
+ }
+
+ // Stores a hash for |key| and |value| in the legacy hash store in
+ // local_state.
+ void PresetLegacyValueHash(const std::string& key,
+ const std::string value) {
+ scoped_ptr<PrefHashStore> pref_hash_store(
+ new PrefHashStoreImpl(kSeed, kDeviceId, true));
+
+ base::StringValue string_value(value);
+ PrefHashStoreImpl(kSeed, kDeviceId, true)
+ .BeginTransaction(scoped_ptr<HashStoreContents>(
+ new PrefServiceHashStoreContents(kHashStoreId, &local_state_)))
+ ->StoreHash(key, &string_value);
+ }
+
+ // Returns true if the store opposite to |store_id| is observed for its next
+ // successful write.
+ bool WasOnSuccessfulWriteCallbackRegistered(MockPrefStoreID store_id) {
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ return !protected_store_successful_write_callback_.is_null();
+ case MOCK_PROTECTED_PREF_STORE:
+ return !unprotected_store_successful_write_callback_.is_null();
+ }
+ NOTREACHED();
+ return false;
+ }
+
+ // Verifies that the (key, value) pairs in |expected_prefs_in_store| are found
+ // in the store identified by |store_id|.
+ void VerifyValuesStored(
+ MockPrefStoreID store_id,
+ const base::StringPairs& expected_prefs_in_store) {
+ base::DictionaryValue* store = NULL;
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ store = unprotected_prefs_.get();
+ break;
+ case MOCK_PROTECTED_PREF_STORE:
+ store = protected_prefs_.get();
+ break;
+ }
+ DCHECK(store);
+
+ for (base::StringPairs::const_iterator it = expected_prefs_in_store.begin();
+ it != expected_prefs_in_store.end(); ++it) {
+ std::string val;
+ EXPECT_TRUE(store->GetString(it->first, &val));
+ EXPECT_EQ(it->second, val);
+ }
+ }
+
+ // Determines whether |expected_pref_in_hash_store| has a hash in the hash
+ // store identified by |store_id|.
+ bool ContainsHash(MockPrefStoreID store_id,
+ std::string expected_pref_in_hash_store) {
+ base::DictionaryValue* store = NULL;
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ store = unprotected_prefs_.get();
+ break;
+ case MOCK_PROTECTED_PREF_STORE:
+ store = protected_prefs_.get();
+ break;
+ }
+ DCHECK(store);
+ const base::DictionaryValue* hash_store_contents =
+ DictionaryHashStoreContents(store).GetContents();
+ return hash_store_contents &&
+ hash_store_contents->GetString(expected_pref_in_hash_store,
+ static_cast<std::string*>(NULL));
+ }
+
+ // Determines whether |expected_pref_in_hash_store| has a hash in the Local
+ // State hash store.
+ bool ContainsLegacyHash(const std::string& expected_pref_in_hash_store) {
+ const base::DictionaryValue* hash_store_contents =
+ PrefServiceHashStoreContents(kHashStoreId, &local_state_).GetContents();
+ return hash_store_contents &&
+ hash_store_contents->GetString(expected_pref_in_hash_store,
+ static_cast<std::string*>(NULL));
+ }
+
+ // Both stores need to hand their prefs over in order for migration to kick
+ // in.
+ void HandPrefsToMigrator(MockPrefStoreID store_id) {
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ mock_unprotected_pref_filter_.FilterOnLoad(
+ base::Bind(&TrackedPreferencesMigrationTest::GetPrefsBack,
+ base::Unretained(this),
+ MOCK_UNPROTECTED_PREF_STORE),
+ unprotected_prefs_.Pass());
+ break;
+ case MOCK_PROTECTED_PREF_STORE:
+ mock_protected_pref_filter_.FilterOnLoad(
+ base::Bind(&TrackedPreferencesMigrationTest::GetPrefsBack,
+ base::Unretained(this),
+ MOCK_PROTECTED_PREF_STORE),
+ protected_prefs_.Pass());
+ break;
+ }
+ }
+
+ bool HasPrefs(MockPrefStoreID store_id) {
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ return unprotected_prefs_;
+ case MOCK_PROTECTED_PREF_STORE:
+ return protected_prefs_;
+ }
+ NOTREACHED();
+ return false;
+ }
+
+ bool StoreModifiedByMigration(MockPrefStoreID store_id) {
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ return migration_modified_unprotected_store_;
+ case MOCK_PROTECTED_PREF_STORE:
+ return migration_modified_protected_store_;
+ }
+ NOTREACHED();
+ return false;
+ }
+
+ bool MigrationCompleted() {
+ return unprotected_store_migration_complete_ &&
+ protected_store_migration_complete_;
+ }
+
+ void SimulateSuccessfulWrite(MockPrefStoreID store_id) {
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ EXPECT_FALSE(unprotected_store_successful_write_callback_.is_null());
+ unprotected_store_successful_write_callback_.Run();
+ unprotected_store_successful_write_callback_.Reset();
+ break;
+ case MOCK_PROTECTED_PREF_STORE:
+ EXPECT_FALSE(protected_store_successful_write_callback_.is_null());
+ protected_store_successful_write_callback_.Run();
+ protected_store_successful_write_callback_.Reset();
+ break;
+ }
+ }
+
+ private:
+ void RegisterSuccessfulWriteClosure(
+ MockPrefStoreID store_id,
+ const base::Closure& successful_write_closure) {
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ EXPECT_TRUE(unprotected_store_successful_write_callback_.is_null());
+ unprotected_store_successful_write_callback_ = successful_write_closure;
+ break;
+ case MOCK_PROTECTED_PREF_STORE:
+ EXPECT_TRUE(protected_store_successful_write_callback_.is_null());
+ protected_store_successful_write_callback_ = successful_write_closure;
+ break;
+ }
+ }
+
+ // Helper given as an InterceptablePrefFilter::FinalizeFilterOnLoadCallback
+ // to the migrator to be invoked when it's done.
+ void GetPrefsBack(MockPrefStoreID store_id,
+ scoped_ptr<base::DictionaryValue> prefs,
+ bool prefs_altered) {
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ EXPECT_FALSE(unprotected_prefs_);
+ unprotected_prefs_ = prefs.Pass();
+ migration_modified_unprotected_store_ = prefs_altered;
+ unprotected_store_migration_complete_ = true;
+ break;
+ case MOCK_PROTECTED_PREF_STORE:
+ EXPECT_FALSE(protected_prefs_);
+ protected_prefs_ = prefs.Pass();
+ migration_modified_protected_store_ = prefs_altered;
+ protected_store_migration_complete_ = true;
+ break;
+ }
+ }
+
+ // Helper given as a cleaning callback to the migrator.
+ void RemovePathFromStore(MockPrefStoreID store_id, const std::string& key) {
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ ASSERT_TRUE(unprotected_prefs_);
+ unprotected_prefs_->RemovePath(key, NULL);
+ break;
+ case MOCK_PROTECTED_PREF_STORE:
+ ASSERT_TRUE(protected_prefs_);
+ protected_prefs_->RemovePath(key, NULL);
+ break;
+ }
+ }
+
+ // Sets |key| to |value| in the test store identified by |store_id| before
+ // migration begins. Does not store a preference hash.
+ void PresetStoreValueOnly(MockPrefStoreID store_id,
+ const std::string& key,
+ const std::string value) {
+ base::DictionaryValue* store = NULL;
+ switch (store_id) {
+ case MOCK_UNPROTECTED_PREF_STORE:
+ store = unprotected_prefs_.get();
+ break;
+ case MOCK_PROTECTED_PREF_STORE:
+ store = protected_prefs_.get();
+ break;
+ }
+ DCHECK(store);
+
+ store->SetString(key, value);
+ }
+
+ static const char kHashStoreId[];
+ static const char kSeed[];
+ static const char kDeviceId[];
+
+ scoped_ptr<base::DictionaryValue> unprotected_prefs_;
+ scoped_ptr<base::DictionaryValue> protected_prefs_;
+
+ SimpleInterceptablePrefFilter mock_unprotected_pref_filter_;
+ SimpleInterceptablePrefFilter mock_protected_pref_filter_;
+
+ base::Closure unprotected_store_successful_write_callback_;
+ base::Closure protected_store_successful_write_callback_;
+
+ bool migration_modified_unprotected_store_;
+ bool migration_modified_protected_store_;
+
+ bool unprotected_store_migration_complete_;
+ bool protected_store_migration_complete_;
+
+ TestingPrefServiceSimple local_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrackedPreferencesMigrationTest);
+};
+
+// static
+const char TrackedPreferencesMigrationTest::kHashStoreId[] = "hash-store-id";
+
+// static
+const char TrackedPreferencesMigrationTest::kSeed[] = "seed";
+
+// static
+const char TrackedPreferencesMigrationTest::kDeviceId[] = "device-id";
+
+} // namespace
+
+TEST_F(TrackedPreferencesMigrationTest, NoMigrationRequired) {
+ PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref,
+ kUnprotectedPrefValue);
+ PresetStoreValue(MOCK_PROTECTED_PREF_STORE, kProtectedPref,
+ kProtectedPrefValue);
+
+ EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+
+ EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+
+ // Hand unprotected prefs to the migrator which should wait for the protected
+ // prefs.
+ HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
+ EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_FALSE(MigrationCompleted());
+
+ // Hand protected prefs to the migrator which should proceed with the
+ // migration synchronously.
+ HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
+ EXPECT_TRUE(MigrationCompleted());
+
+ // Prefs should have been handed back over.
+ EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_FALSE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_FALSE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_FALSE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_FALSE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
+
+ base::StringPairs expected_unprotected_values;
+ expected_unprotected_values.push_back(
+ std::make_pair(kUnprotectedPref, kUnprotectedPrefValue));
+ VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, expected_unprotected_values);
+
+ base::StringPairs expected_protected_values;
+ expected_protected_values.push_back(
+ std::make_pair(kProtectedPref, kProtectedPrefValue));
+ VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
+
+ EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+
+ EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+}
+
+TEST_F(TrackedPreferencesMigrationTest, LegacyHashMigrationOnly) {
+ PresetLegacyStoreValue(
+ MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue);
+ PresetLegacyStoreValue(
+ MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue);
+
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+
+ EXPECT_TRUE(ContainsLegacyHash(kProtectedPref));
+ EXPECT_TRUE(ContainsLegacyHash(kUnprotectedPref));
+
+ // Hand unprotected prefs to the migrator which should wait for the protected
+ // prefs.
+ HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
+ EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_FALSE(MigrationCompleted());
+
+ // Hand protected prefs to the migrator which should proceed with the
+ // migration synchronously.
+ HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
+ EXPECT_TRUE(MigrationCompleted());
+
+ // Prefs should have been handed back over.
+ EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
+
+ // There is no pending cleanup task for the modern hash stores.
+ EXPECT_FALSE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_FALSE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
+
+ // Both stores were modified as hashes were moved from Local State.
+ EXPECT_TRUE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
+
+ base::StringPairs expected_unprotected_values;
+ expected_unprotected_values.push_back(
+ std::make_pair(kUnprotectedPref, kUnprotectedPrefValue));
+ VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, expected_unprotected_values);
+
+ base::StringPairs expected_protected_values;
+ expected_protected_values.push_back(
+ std::make_pair(kProtectedPref, kProtectedPrefValue));
+ VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
+
+ EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+
+ EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+
+ // The Local State hash store will not be reset until the next run.
+ EXPECT_TRUE(ContainsLegacyHash(kProtectedPref));
+ EXPECT_TRUE(ContainsLegacyHash(kUnprotectedPref));
+
+ Reset();
+
+ HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
+ HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
+ EXPECT_TRUE(MigrationCompleted());
+
+ // Neither store was modified.
+ EXPECT_FALSE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_FALSE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
+
+ EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+
+ EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+
+ EXPECT_FALSE(ContainsLegacyHash(kProtectedPref));
+ EXPECT_FALSE(ContainsLegacyHash(kUnprotectedPref));
+}
+
+TEST_F(TrackedPreferencesMigrationTest, FullMigrationWithLegacyHashStore) {
+ // Store some values with matching MACs in Local State.
+ PresetLegacyStoreValue(
+ MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue);
+ PresetLegacyStoreValue(MOCK_UNPROTECTED_PREF_STORE,
+ kPreviouslyUnprotectedPref,
+ kPreviouslyUnprotectedPrefValue);
+ PresetLegacyStoreValue(
+ MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue);
+ PresetLegacyStoreValue(MOCK_PROTECTED_PREF_STORE,
+ kPreviouslyProtectedPref,
+ kPreviouslyProtectedPrefValue);
+
+ // Verify that there are no MACs in Preferences or Secure Preferences.
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ // Verify that there are MACs in Local State.
+ EXPECT_TRUE(ContainsLegacyHash(kUnprotectedPref));
+ EXPECT_TRUE(ContainsLegacyHash(kPreviouslyUnprotectedPref));
+ EXPECT_TRUE(ContainsLegacyHash(kProtectedPref));
+ EXPECT_TRUE(ContainsLegacyHash(kPreviouslyProtectedPref));
+
+ // Perform a first-pass migration.
+ HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
+ HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
+ EXPECT_TRUE(MigrationCompleted());
+
+ // All values should have been moved to their preferred locations, including
+ // MACs.
+ base::StringPairs expected_unprotected_values;
+ expected_unprotected_values.push_back(
+ std::make_pair(kUnprotectedPref, kUnprotectedPrefValue));
+ expected_unprotected_values.push_back(
+ std::make_pair(kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
+ base::StringPairs expected_protected_values;
+ expected_protected_values.push_back(
+ std::make_pair(kProtectedPref, kProtectedPrefValue));
+ expected_protected_values.push_back(std::make_pair(
+ kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
+
+ VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, expected_unprotected_values);
+ VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
+
+ EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+
+ EXPECT_FALSE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ // Removing the values from their previous locations is deferred until the new
+ // locations are persisted.
+ EXPECT_TRUE(ContainsLegacyHash(kUnprotectedPref));
+ EXPECT_TRUE(ContainsLegacyHash(kPreviouslyUnprotectedPref));
+ EXPECT_TRUE(ContainsLegacyHash(kProtectedPref));
+ EXPECT_TRUE(ContainsLegacyHash(kPreviouslyProtectedPref));
+
+ EXPECT_TRUE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
+
+ SimulateSuccessfulWrite(MOCK_UNPROTECTED_PREF_STORE);
+ SimulateSuccessfulWrite(MOCK_PROTECTED_PREF_STORE);
+
+ Reset();
+
+ HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
+ HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
+ EXPECT_TRUE(MigrationCompleted());
+
+ // In this run the MACs should have been removed from their previous
+ // locations. There is no more pending action.
+ EXPECT_FALSE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_FALSE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
+
+ EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ EXPECT_FALSE(ContainsLegacyHash(kUnprotectedPref));
+ EXPECT_FALSE(ContainsLegacyHash(kPreviouslyUnprotectedPref));
+ EXPECT_FALSE(ContainsLegacyHash(kProtectedPref));
+ EXPECT_FALSE(ContainsLegacyHash(kPreviouslyProtectedPref));
+
+ VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE, expected_unprotected_values);
+ VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
+}
+
+TEST_F(TrackedPreferencesMigrationTest, FullMigration) {
+ PresetStoreValue(
+ MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue);
+ PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE,
+ kPreviouslyUnprotectedPref,
+ kPreviouslyUnprotectedPrefValue);
+ PresetStoreValue(
+ MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue);
+ PresetStoreValue(MOCK_PROTECTED_PREF_STORE,
+ kPreviouslyProtectedPref,
+ kPreviouslyProtectedPrefValue);
+
+ EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
+ EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_FALSE(MigrationCompleted());
+
+ HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
+ EXPECT_TRUE(MigrationCompleted());
+
+ EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_TRUE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_TRUE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
+
+ // Values should have been migrated to their store, but migrated values should
+ // still remain in the source store until cleanup tasks are later invoked.
+ {
+ base::StringPairs expected_unprotected_values;
+ expected_unprotected_values.push_back(std::make_pair(
+ kUnprotectedPref, kUnprotectedPrefValue));
+ expected_unprotected_values.push_back(std::make_pair(
+ kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
+ expected_unprotected_values.push_back(std::make_pair(
+ kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
+ VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE,
+ expected_unprotected_values);
+
+ base::StringPairs expected_protected_values;
+ expected_protected_values.push_back(std::make_pair(
+ kProtectedPref, kProtectedPrefValue));
+ expected_protected_values.push_back(std::make_pair(
+ kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
+ expected_unprotected_values.push_back(std::make_pair(
+ kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
+ VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
+
+ EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+ }
+
+ // A successful write of the protected pref store should result in a clean up
+ // of the unprotected store.
+ SimulateSuccessfulWrite(MOCK_PROTECTED_PREF_STORE);
+
+ {
+ base::StringPairs expected_unprotected_values;
+ expected_unprotected_values.push_back(std::make_pair(
+ kUnprotectedPref, kUnprotectedPrefValue));
+ expected_unprotected_values.push_back(std::make_pair(
+ kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
+ VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE,
+ expected_unprotected_values);
+
+ base::StringPairs expected_protected_values;
+ expected_protected_values.push_back(std::make_pair(
+ kProtectedPref, kProtectedPrefValue));
+ expected_protected_values.push_back(std::make_pair(
+ kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
+ expected_unprotected_values.push_back(std::make_pair(
+ kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
+ VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
+ }
+
+ SimulateSuccessfulWrite(MOCK_UNPROTECTED_PREF_STORE);
+
+ {
+ base::StringPairs expected_unprotected_values;
+ expected_unprotected_values.push_back(std::make_pair(
+ kUnprotectedPref, kUnprotectedPrefValue));
+ expected_unprotected_values.push_back(std::make_pair(
+ kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
+ VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE,
+ expected_unprotected_values);
+
+ base::StringPairs expected_protected_values;
+ expected_protected_values.push_back(std::make_pair(
+ kProtectedPref, kProtectedPrefValue));
+ expected_protected_values.push_back(std::make_pair(
+ kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
+ VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
+ }
+
+ // Hashes are not cleaned up yet.
+ EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ Reset();
+
+ HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
+ HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
+ EXPECT_TRUE(MigrationCompleted());
+
+ // Hashes are cleaned up.
+ EXPECT_TRUE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_FALSE(ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_UNPROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+
+ EXPECT_FALSE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kUnprotectedPref));
+ EXPECT_TRUE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyUnprotectedPref));
+ EXPECT_TRUE(ContainsHash(MOCK_PROTECTED_PREF_STORE, kProtectedPref));
+ EXPECT_FALSE(
+ ContainsHash(MOCK_PROTECTED_PREF_STORE, kPreviouslyProtectedPref));
+}
+
+TEST_F(TrackedPreferencesMigrationTest, CleanupOnly) {
+ // Already migrated; only cleanup needed.
+ PresetStoreValue(
+ MOCK_UNPROTECTED_PREF_STORE, kUnprotectedPref, kUnprotectedPrefValue);
+ PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE,
+ kPreviouslyProtectedPref,
+ kPreviouslyProtectedPrefValue);
+ PresetStoreValue(MOCK_UNPROTECTED_PREF_STORE,
+ kPreviouslyUnprotectedPref,
+ kPreviouslyUnprotectedPrefValue);
+ PresetStoreValue(
+ MOCK_PROTECTED_PREF_STORE, kProtectedPref, kProtectedPrefValue);
+ PresetStoreValue(MOCK_PROTECTED_PREF_STORE,
+ kPreviouslyProtectedPref,
+ kPreviouslyProtectedPrefValue);
+ PresetStoreValue(MOCK_PROTECTED_PREF_STORE,
+ kPreviouslyUnprotectedPref,
+ kPreviouslyUnprotectedPrefValue);
+
+ HandPrefsToMigrator(MOCK_UNPROTECTED_PREF_STORE);
+ EXPECT_FALSE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_FALSE(MigrationCompleted());
+
+ HandPrefsToMigrator(MOCK_PROTECTED_PREF_STORE);
+ EXPECT_TRUE(MigrationCompleted());
+
+ EXPECT_TRUE(HasPrefs(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_TRUE(HasPrefs(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_FALSE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_FALSE(
+ WasOnSuccessfulWriteCallbackRegistered(MOCK_PROTECTED_PREF_STORE));
+ EXPECT_FALSE(StoreModifiedByMigration(MOCK_UNPROTECTED_PREF_STORE));
+ EXPECT_FALSE(StoreModifiedByMigration(MOCK_PROTECTED_PREF_STORE));
+
+ // Cleanup should happen synchronously if the values were already present in
+ // their destination stores.
+ {
+ base::StringPairs expected_unprotected_values;
+ expected_unprotected_values.push_back(std::make_pair(
+ kUnprotectedPref, kUnprotectedPrefValue));
+ expected_unprotected_values.push_back(std::make_pair(
+ kPreviouslyProtectedPref, kPreviouslyProtectedPrefValue));
+ VerifyValuesStored(MOCK_UNPROTECTED_PREF_STORE,
+ expected_unprotected_values);
+
+ base::StringPairs expected_protected_values;
+ expected_protected_values.push_back(std::make_pair(
+ kProtectedPref, kProtectedPrefValue));
+ expected_protected_values.push_back(std::make_pair(
+ kPreviouslyUnprotectedPref, kPreviouslyUnprotectedPrefValue));
+ VerifyValuesStored(MOCK_PROTECTED_PREF_STORE, expected_protected_values);
+ }
+}
diff --git a/chromium/components/user_prefs/tracked/tracked_split_preference.cc b/chromium/components/user_prefs/tracked/tracked_split_preference.cc
new file mode 100644
index 00000000000..37bac10b760
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_split_preference.cc
@@ -0,0 +1,92 @@
+// 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/user_prefs/tracked/tracked_split_preference.h"
+
+#include <vector>
+
+#include "base/logging.h"
+#include "base/values.h"
+#include "components/user_prefs/tracked/pref_hash_store_transaction.h"
+#include "components/user_prefs/tracked/tracked_preference_validation_delegate.h"
+
+TrackedSplitPreference::TrackedSplitPreference(
+ const std::string& pref_path,
+ size_t reporting_id,
+ size_t reporting_ids_count,
+ PrefHashFilter::EnforcementLevel enforcement_level,
+ PrefHashFilter::ValueType value_type,
+ TrackedPreferenceValidationDelegate* delegate)
+ : pref_path_(pref_path),
+ helper_(pref_path,
+ reporting_id,
+ reporting_ids_count,
+ enforcement_level,
+ value_type),
+ delegate_(delegate) {
+}
+
+void TrackedSplitPreference::OnNewValue(
+ const base::Value* value,
+ PrefHashStoreTransaction* transaction) const {
+ const base::DictionaryValue* dict_value = NULL;
+ if (value && !value->GetAsDictionary(&dict_value)) {
+ NOTREACHED();
+ return;
+ }
+ transaction->StoreSplitHash(pref_path_, dict_value);
+}
+
+bool TrackedSplitPreference::EnforceAndReport(
+ base::DictionaryValue* pref_store_contents,
+ PrefHashStoreTransaction* transaction) const {
+ base::DictionaryValue* dict_value = NULL;
+ if (!pref_store_contents->GetDictionary(pref_path_, &dict_value) &&
+ pref_store_contents->Get(pref_path_, NULL)) {
+ // There should be a dictionary or nothing at |pref_path_|.
+ NOTREACHED();
+ return false;
+ }
+
+ std::vector<std::string> invalid_keys;
+ PrefHashStoreTransaction::ValueState value_state =
+ transaction->CheckSplitValue(pref_path_, dict_value, &invalid_keys);
+
+ if (value_state == PrefHashStoreTransaction::CHANGED)
+ helper_.ReportSplitPreferenceChangedCount(invalid_keys.size());
+
+ helper_.ReportValidationResult(value_state);
+
+ TrackedPreferenceHelper::ResetAction reset_action =
+ helper_.GetAction(value_state);
+ if (delegate_) {
+ delegate_->OnSplitPreferenceValidation(pref_path_, dict_value, invalid_keys,
+ value_state, helper_.IsPersonal());
+ }
+ helper_.ReportAction(reset_action);
+
+ bool was_reset = false;
+ if (reset_action == TrackedPreferenceHelper::DO_RESET) {
+ if (value_state == PrefHashStoreTransaction::CHANGED) {
+ DCHECK(!invalid_keys.empty());
+
+ for (std::vector<std::string>::const_iterator it = invalid_keys.begin();
+ it != invalid_keys.end(); ++it) {
+ dict_value->Remove(*it, NULL);
+ }
+ } else {
+ pref_store_contents->RemovePath(pref_path_, NULL);
+ }
+ was_reset = true;
+ }
+
+ if (value_state != PrefHashStoreTransaction::UNCHANGED) {
+ // Store the hash for the new value (whether it was reset or not).
+ const base::DictionaryValue* new_dict_value = NULL;
+ pref_store_contents->GetDictionary(pref_path_, &new_dict_value);
+ transaction->StoreSplitHash(pref_path_, new_dict_value);
+ }
+
+ return was_reset;
+}
diff --git a/chromium/components/user_prefs/tracked/tracked_split_preference.h b/chromium/components/user_prefs/tracked/tracked_split_preference.h
new file mode 100644
index 00000000000..04c21282853
--- /dev/null
+++ b/chromium/components/user_prefs/tracked/tracked_split_preference.h
@@ -0,0 +1,47 @@
+// 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_USER_PREFS_TRACKED_TRACKED_SPLIT_PREFERENCE_H_
+#define COMPONENTS_USER_PREFS_TRACKED_TRACKED_SPLIT_PREFERENCE_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "components/user_prefs/tracked/pref_hash_filter.h"
+#include "components/user_prefs/tracked/tracked_preference.h"
+#include "components/user_prefs/tracked/tracked_preference_helper.h"
+
+class TrackedPreferenceValidationDelegate;
+
+// A TrackedSplitPreference must be tracking a dictionary pref. Each top-level
+// entry in its dictionary is tracked and enforced independently. An optional
+// delegate is notified of the status of the preference during enforcement.
+// Note: preferences using this strategy must be kept in sync with
+// TrackedSplitPreferences in histograms.xml.
+class TrackedSplitPreference : public TrackedPreference {
+ public:
+ // Constructs a TrackedSplitPreference. |pref_path| must be a dictionary pref.
+ TrackedSplitPreference(const std::string& pref_path,
+ size_t reporting_id,
+ size_t reporting_ids_count,
+ PrefHashFilter::EnforcementLevel enforcement_level,
+ PrefHashFilter::ValueType value_type,
+ TrackedPreferenceValidationDelegate* delegate);
+
+ // TrackedPreference implementation.
+ void OnNewValue(const base::Value* value,
+ PrefHashStoreTransaction* transaction) const override;
+ bool EnforceAndReport(base::DictionaryValue* pref_store_contents,
+ PrefHashStoreTransaction* transaction) const override;
+
+ private:
+ const std::string pref_path_;
+ const TrackedPreferenceHelper helper_;
+ TrackedPreferenceValidationDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrackedSplitPreference);
+};
+
+#endif // COMPONENTS_USER_PREFS_TRACKED_TRACKED_SPLIT_PREFERENCE_H_
diff --git a/chromium/components/user_prefs/user_prefs.cc b/chromium/components/user_prefs/user_prefs.cc
new file mode 100644
index 00000000000..3ddff9bfc10
--- /dev/null
+++ b/chromium/components/user_prefs/user_prefs.cc
@@ -0,0 +1,46 @@
+// 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/user_prefs/user_prefs.h"
+
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "base/prefs/pref_service.h"
+
+namespace user_prefs {
+
+namespace {
+
+void* UserDataKey() {
+ // We just need a unique constant. Use the address of a static that
+ // COMDAT folding won't touch in an optimizing linker.
+ static int data_key = 0;
+ return reinterpret_cast<void*>(&data_key);
+}
+
+} // namespace
+
+// static
+PrefService* UserPrefs::Get(base::SupportsUserData* context) {
+ DCHECK(context);
+ DCHECK(context->GetUserData(UserDataKey()));
+ return static_cast<UserPrefs*>(
+ context->GetUserData(UserDataKey()))->prefs_;
+}
+
+// static
+void UserPrefs::Set(base::SupportsUserData* context, PrefService* prefs) {
+ DCHECK(context);
+ DCHECK(prefs);
+ DCHECK(!context->GetUserData(UserDataKey()));
+ context->SetUserData(UserDataKey(), new UserPrefs(prefs));
+}
+
+UserPrefs::UserPrefs(PrefService* prefs) : prefs_(prefs) {
+}
+
+UserPrefs::~UserPrefs() {
+}
+
+} // namespace user_prefs
diff --git a/chromium/components/user_prefs/user_prefs.h b/chromium/components/user_prefs/user_prefs.h
new file mode 100644
index 00000000000..ceea4f02f32
--- /dev/null
+++ b/chromium/components/user_prefs/user_prefs.h
@@ -0,0 +1,42 @@
+// 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_USER_PREFS_USER_PREFS_H_
+#define COMPONENTS_USER_PREFS_USER_PREFS_H_
+
+#include "base/basictypes.h"
+#include "base/supports_user_data.h"
+#include "components/user_prefs/user_prefs_export.h"
+
+class PrefService;
+
+namespace user_prefs {
+
+// Components may use preferences associated with a given user. These hang off
+// of base::SupportsUserData and can be retrieved using UserPrefs::Get().
+//
+// It is up to the embedder to create and own the PrefService and attach it to
+// base::SupportsUserData using the UserPrefs::Set() function.
+class USER_PREFS_EXPORT UserPrefs : public base::SupportsUserData::Data {
+ public:
+ // Retrieves the PrefService for a given context, or null if none is attached.
+ static PrefService* Get(base::SupportsUserData* context);
+
+ // Hangs the specified |prefs| off of |context|. Should be called
+ // only once per context.
+ static void Set(base::SupportsUserData* context, PrefService* prefs);
+
+ private:
+ explicit UserPrefs(PrefService* prefs);
+ ~UserPrefs() override;
+
+ // Non-owning; owned by embedder.
+ PrefService* prefs_;
+
+ DISALLOW_COPY_AND_ASSIGN(UserPrefs);
+};
+
+} // namespace user_prefs
+
+#endif // COMPONENTS_USER_PREFS_USER_PREFS_H_
diff --git a/chromium/components/user_prefs/user_prefs_export.h b/chromium/components/user_prefs/user_prefs_export.h
new file mode 100644
index 00000000000..af7c0f90417
--- /dev/null
+++ b/chromium/components/user_prefs/user_prefs_export.h
@@ -0,0 +1,29 @@
+// 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_USER_PREFS_USER_PREFS_EXPORT_H_
+#define COMPONENTS_USER_PREFS_USER_PREFS_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(USER_PREFS_IMPLEMENTATION)
+#define USER_PREFS_EXPORT __declspec(dllexport)
+#else
+#define USER_PREFS_EXPORT __declspec(dllimport)
+#endif // defined(USER_PREFS_IMPLEMENTATION)
+
+#else // defined(WIN32)
+#if defined(USER_PREFS_IMPLEMENTATION)
+#define USER_PREFS_EXPORT __attribute__((visibility("default")))
+#else
+#define USER_PREFS_EXPORT
+#endif
+#endif
+
+#else // defined(COMPONENT_BUILD)
+#define USER_PREFS_EXPORT
+#endif
+
+#endif // COMPONENTS_USER_PREFS_USER_PREFS_EXPORT_H_
diff --git a/chromium/components/variations.gypi b/chromium/components/variations.gypi
index 64592134a08..d1fc8c6712a 100644
--- a/chromium/components/variations.gypi
+++ b/chromium/components/variations.gypi
@@ -16,7 +16,11 @@
# adding extra dependencies without first checking with OWNERS.
'../base/base.gyp:base',
'../base/base.gyp:base_prefs',
+ '../crypto/crypto.gyp:crypto',
'../third_party/mt19937ar/mt19937ar.gyp:mt19937ar',
+ '../third_party/protobuf/protobuf.gyp:protobuf_lite',
+ 'compression',
+ 'crash_core_common',
],
'sources': [
# Note: sources list duplicated in GN build.
@@ -30,6 +34,8 @@
'variations/caching_permuted_entropy_provider.h',
'variations/entropy_provider.cc',
'variations/entropy_provider.h',
+ 'variations/experiment_labels.cc',
+ 'variations/experiment_labels.h',
'variations/metrics_util.cc',
'variations/metrics_util.h',
'variations/pref_names.cc',
@@ -44,10 +50,24 @@
'variations/study_filtering.h',
'variations/variations_associated_data.cc',
'variations/variations_associated_data.h',
+ 'variations/variations_experiment_util.cc',
+ 'variations/variations_experiment_util.h',
+ 'variations/variations_request_scheduler.cc',
+ 'variations/variations_request_scheduler.h',
+ 'variations/variations_request_scheduler_mobile.cc',
+ 'variations/variations_request_scheduler_mobile.h',
'variations/variations_seed_processor.cc',
'variations/variations_seed_processor.h',
'variations/variations_seed_simulator.cc',
'variations/variations_seed_simulator.h',
+ 'variations/variations_seed_store.cc',
+ 'variations/variations_seed_store.h',
+ 'variations/variations_switches.cc',
+ 'variations/variations_switches.h',
+ 'variations/variations_url_constants.cc',
+ 'variations/variations_url_constants.h',
+ 'variations/variations_util.cc',
+ 'variations/variations_util.h',
],
'variables': {
'proto_in_dir': 'variations/proto',
@@ -60,6 +80,39 @@
'variations_jni_headers',
],
}],
+ ['OS!="android" and OS!="ios"', {
+ 'sources!': [
+ 'variations/variations_request_scheduler_mobile.cc',
+ ],
+ }],
+ ],
+ },
+ {
+ # GN version: //components/variations/service
+ 'target_name': 'variations_service',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../base/base.gyp:base_prefs',
+ '../net/net.gyp:net',
+ '../ui/base/ui_base.gyp:ui_base',
+ 'data_use_measurement_core',
+ 'metrics',
+ 'network_time',
+ 'pref_registry',
+ 'variations',
+ 'version_info',
+ 'web_resource',
+ ],
+ 'sources': [
+ 'variations/service/ui_string_overrider.h',
+ 'variations/service/ui_string_overrider.cc',
+ 'variations/service/variations_service.cc',
+ 'variations/service/variations_service.h',
+ 'variations/service/variations_service_client.h',
],
},
{
@@ -74,11 +127,11 @@
'../net/net.gyp:net',
'../url/url.gyp:url_lib',
'components.gyp:google_core_browser',
- "components.gyp:metrics",
+ 'components.gyp:metrics',
'variations',
],
'export_dependent_settings': [
- "components.gyp:metrics",
+ 'components.gyp:metrics',
],
'sources': [
'variations/net/variations_http_header_provider.cc',
diff --git a/chromium/components/version_info.grdp b/chromium/components/version_info.grdp
new file mode 100644
index 00000000000..934d17d9bbc
--- /dev/null
+++ b/chromium/components/version_info.grdp
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+
+ <message name="IDS_ABOUT_VERSION_UNOFFICIAL" desc="unofficial build on the about:version page">
+ Developer Build
+ </message>
+
+</grit-part>
diff --git a/chromium/components/version_info.gypi b/chromium/components/version_info.gypi
new file mode 100644
index 00000000000..15159c45ee6
--- /dev/null
+++ b/chromium/components/version_info.gypi
@@ -0,0 +1,116 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'variables': {
+ # Some plaform want to override part of the version number generation
+ # (for example iOS uses a different value for PATCH level for canary).
+ # This can be done settings "extra_version_path" variable to the path
+ # of a file with the corresponding value overrides. If present it will
+ # be loaded after all other input files.
+ 'extra_version_name': '',
+ },
+ 'targets': [
+ {
+ # GN version: //components/version_info
+ 'target_name': 'version_info',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../ui/base/ui_base.gyp:ui_base',
+ 'components_strings.gyp:components_strings',
+ 'generate_version_info',
+ ],
+ 'sources': [
+ 'version_info/version_info.cc',
+ 'version_info/version_info.h',
+ ],
+ 'export_dependent_settings': [
+ 'generate_version_info',
+ ],
+ },
+ {
+ # GN version: //components/version_info:generate_version
+ 'target_name': 'generate_version_info',
+ 'type': 'none',
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ '<(SHARED_INTERMEDIATE_DIR)',
+ ],
+ },
+ # Because generate_version_info generates a header, the target must set
+ # the hard_dependency flag.
+ 'hard_dependency': 1,
+ 'actions': [
+ {
+ 'action_name': 'generation_version_info',
+ 'message': 'Generating version information',
+ 'variables': {
+ 'extra_version_flags': [],
+ 'lastchange_path': '../build/util/LASTCHANGE',
+ 'version_py_path': '../build/util/version.py',
+ 'template_input_path': 'version_info/version_info_values.h.version',
+ # Use VERSION and BRANDING files from //chrome even if this is bad
+ # dependency until they are moved to src/ for VERSION and to the
+ # version_info component for BRANDING. Synchronisation with TPM and
+ # all release script is required for thoses moves. They are tracked
+ # by issues http://crbug.com/512347 and http://crbug.com/513603.
+ 'version_path': '../chrome/VERSION',
+ 'branding_path': '../chrome/app/theme/<(branding_path_component)/BRANDING',
+ },
+ 'inputs': [
+ '<(version_py_path)',
+ '<(template_input_path)',
+ '<(version_path)',
+ '<(branding_path)',
+ '<(lastchange_path)',
+ ],
+ 'outputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/components/version_info/version_info_values.h',
+ ],
+ 'action': [
+ 'python',
+ '<(version_py_path)',
+ '-f', '<(version_path)',
+ '-f', '<(branding_path)',
+ '-f', '<(lastchange_path)',
+ '<@(extra_version_flags)',
+ '<(template_input_path)',
+ '<@(_outputs)',
+ ],
+ 'conditions': [
+ ['extra_version_name!=""', {
+ 'variables': {
+ 'extra_version_flags': [
+ '-f', '<(extra_version_name)',
+ ],
+ },
+ 'inputs': [
+ '<(extra_version_name)'
+ ],
+ }],
+ ],
+ },
+ ],
+ },
+ ],
+ 'conditions': [
+ ['OS=="ios"', {
+ 'variables': {
+ # Use nested 'variables' to workaround how variables work with gyp (no
+ # determined ordering and thuse it is not possible to define a variable
+ # in function of another).
+ 'variables': {
+ # Path to the file used to override the version PATH level on iOS.
+ # Default to ios/build/util/VERSION.
+ 'ios_extra_version_path%': '../ios/build/util/VERSION',
+ },
+ 'extra_version_name': '<(ios_extra_version_path)'
+ },
+ }],
+ ],
+}
diff --git a/chromium/components/visitedlink/browser/BUILD.gn b/chromium/components/visitedlink/browser/BUILD.gn
index 4fce197308a..fa2e70ce83e 100644
--- a/chromium/components/visitedlink/browser/BUILD.gn
+++ b/chromium/components/visitedlink/browser/BUILD.gn
@@ -2,8 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-static_library("browser") {
- output_name = "visitedlink_browser"
+source_set("browser") {
sources = [
"visitedlink_delegate.h",
"visitedlink_event_listener.cc",
diff --git a/chromium/components/visitedlink/browser/visitedlink_event_listener.h b/chromium/components/visitedlink/browser/visitedlink_event_listener.h
index 2b6aa726d0f..f211fce0561 100644
--- a/chromium/components/visitedlink/browser/visitedlink_event_listener.h
+++ b/chromium/components/visitedlink/browser/visitedlink_event_listener.h
@@ -47,7 +47,7 @@ class VisitedLinkEventListener : public VisitedLinkMaster::Listener,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
- base::OneShotTimer<VisitedLinkEventListener> coalesce_timer_;
+ base::OneShotTimer coalesce_timer_;
VisitedLinkCommon::Fingerprints pending_visited_links_;
content::NotificationRegistrar registrar_;
diff --git a/chromium/components/visitedlink/common/BUILD.gn b/chromium/components/visitedlink/common/BUILD.gn
index 2c472d012df..712e8d09efe 100644
--- a/chromium/components/visitedlink/common/BUILD.gn
+++ b/chromium/components/visitedlink/common/BUILD.gn
@@ -2,8 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-static_library("common") {
- output_name = "visitedlink_common"
+source_set("common") {
sources = [
"visitedlink_common.cc",
"visitedlink_common.h",
diff --git a/chromium/components/visitedlink/renderer/BUILD.gn b/chromium/components/visitedlink/renderer/BUILD.gn
index 33618cccb69..2b95684a48b 100644
--- a/chromium/components/visitedlink/renderer/BUILD.gn
+++ b/chromium/components/visitedlink/renderer/BUILD.gn
@@ -2,19 +2,18 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-if (!is_ios) {
- static_library("renderer") {
- output_name = "visitedlink_renderer"
- sources = [
- "visitedlink_slave.cc",
- "visitedlink_slave.h",
- ]
+assert(!is_ios)
- deps = [
- "//base",
- "//content/public/common",
- "//content/public/renderer",
- "//third_party/WebKit/public:blink",
- ]
- }
+source_set("renderer") {
+ sources = [
+ "visitedlink_slave.cc",
+ "visitedlink_slave.h",
+ ]
+
+ deps = [
+ "//base",
+ "//content/public/common",
+ "//content/public/renderer",
+ "//third_party/WebKit/public:blink",
+ ]
}
diff --git a/chromium/components/web_cache/browser/BUILD.gn b/chromium/components/web_cache/browser/BUILD.gn
index b9ba85bd634..e64a2d5ca4a 100644
--- a/chromium/components/web_cache/browser/BUILD.gn
+++ b/chromium/components/web_cache/browser/BUILD.gn
@@ -2,8 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-static_library("browser") {
- output_name = "web_cache_browser"
+source_set("browser") {
sources = [
"web_cache_manager.cc",
"web_cache_manager.h",
@@ -13,8 +12,22 @@ static_library("browser") {
deps = [
"//base",
+ "//base:prefs",
"//components/web_cache/common",
"//content/public/browser",
"//third_party/WebKit/public:blink",
]
}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "web_cache_manager_unittest.cc",
+ ]
+ deps = [
+ ":browser",
+ "//base",
+ "//content/test:test_support",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/web_cache/browser/web_cache_manager.cc b/chromium/components/web_cache/browser/web_cache_manager.cc
index dfed012ebfb..3972ea5c073 100644
--- a/chromium/components/web_cache/browser/web_cache_manager.cc
+++ b/chromium/components/web_cache/browser/web_cache_manager.cc
@@ -56,7 +56,7 @@ int GetDefaultCacheSize() {
// static
WebCacheManager* WebCacheManager::GetInstance() {
- return Singleton<WebCacheManager>::get();
+ return base::Singleton<WebCacheManager>::get();
}
WebCacheManager::WebCacheManager()
diff --git a/chromium/components/web_cache/browser/web_cache_manager.h b/chromium/components/web_cache/browser/web_cache_manager.h
index 0d2d3ffb644..230d6fd4930 100644
--- a/chromium/components/web_cache/browser/web_cache_manager.h
+++ b/chromium/components/web_cache/browser/web_cache_manager.h
@@ -21,8 +21,11 @@
#include "content/public/browser/notification_registrar.h"
#include "third_party/WebKit/public/web/WebCache.h"
+namespace base {
template<typename Type>
struct DefaultSingletonTraits;
+} // namespace base
+
class PrefRegistrySimple;
namespace web_cache {
@@ -124,7 +127,7 @@ class WebCacheManager : public content::NotificationObserver {
// This class is a singleton. Do not instantiate directly.
WebCacheManager();
- friend struct DefaultSingletonTraits<WebCacheManager>;
+ friend struct base::DefaultSingletonTraits<WebCacheManager>;
~WebCacheManager() override;
diff --git a/chromium/components/web_cache/common/BUILD.gn b/chromium/components/web_cache/common/BUILD.gn
index 5c7b2ef196c..d4b7ac70a6a 100644
--- a/chromium/components/web_cache/common/BUILD.gn
+++ b/chromium/components/web_cache/common/BUILD.gn
@@ -2,8 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-static_library("common") {
- output_name = "web_cache_common"
+source_set("common") {
sources = [
"web_cache_message_generator.cc",
"web_cache_message_generator.h",
diff --git a/chromium/components/web_cache/renderer/BUILD.gn b/chromium/components/web_cache/renderer/BUILD.gn
index cdd703a8145..a9e89683136 100644
--- a/chromium/components/web_cache/renderer/BUILD.gn
+++ b/chromium/components/web_cache/renderer/BUILD.gn
@@ -2,14 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-static_library("renderer") {
- output_name = "web_cache_renderer"
+source_set("renderer") {
sources = [
"web_cache_render_process_observer.cc",
"web_cache_render_process_observer.h",
]
deps = [
+ "//base",
"//components/web_cache/common",
"//content/public/renderer",
"//third_party/WebKit/public:blink",
diff --git a/chromium/components/web_modal.gypi b/chromium/components/web_modal.gypi
index 7cc7aab84f5..cb257daa647 100644
--- a/chromium/components/web_modal.gypi
+++ b/chromium/components/web_modal.gypi
@@ -20,8 +20,6 @@
# Note: sources list duplicated in GN build.
'web_modal/modal_dialog_host.cc',
'web_modal/modal_dialog_host.h',
- 'web_modal/popup_manager.cc',
- 'web_modal/popup_manager.h',
'web_modal/single_web_contents_dialog_manager.h',
'web_modal/web_contents_modal_dialog_host.cc',
'web_modal/web_contents_modal_dialog_host.h',
diff --git a/chromium/components/web_resource.gypi b/chromium/components/web_resource.gypi
index b300556ebd9..59e25510995 100644
--- a/chromium/components/web_resource.gypi
+++ b/chromium/components/web_resource.gypi
@@ -13,11 +13,20 @@
],
'dependencies': [
'../base/base.gyp:base',
+ '../ui/base/ui_base.gyp:ui_base',
'../net/net.gyp:net',
+ 'pref_registry',
+ 'version_info',
],
'sources': [
'web_resource/eula_accepted_notifier.cc',
'web_resource/eula_accepted_notifier.h',
+ 'web_resource/notification_promo.cc',
+ 'web_resource/notification_promo.h',
+ 'web_resource/notification_promo_mobile_ntp.cc',
+ 'web_resource/notification_promo_mobile_ntp.h',
+ 'web_resource/promo_resource_service.cc',
+ 'web_resource/promo_resource_service.h',
'web_resource/resource_request_allowed_notifier.cc',
'web_resource/resource_request_allowed_notifier.h',
'web_resource/web_resource_pref_names.cc',
@@ -27,6 +36,14 @@
'web_resource/web_resource_switches.cc',
'web_resource/web_resource_switches.h',
],
+ 'conditions': [
+ ['OS!="ios" and OS!="android"', {
+ 'sources!': [
+ 'web_resource/notification_promo_mobile_ntp.cc',
+ 'web_resource/notification_promo_mobile_ntp.h',
+ ],
+ }],
+ ],
},
{
# GN version: //components/web_resources:test_support
diff --git a/chromium/components/webcrypto/BUILD.gn b/chromium/components/webcrypto/BUILD.gn
index f14aed5e4d5..aebf172f3c4 100644
--- a/chromium/components/webcrypto/BUILD.gn
+++ b/chromium/components/webcrypto/BUILD.gn
@@ -11,21 +11,48 @@ source_set("webcrypto") {
"algorithm_dispatch.h",
"algorithm_implementation.cc",
"algorithm_implementation.h",
+ "algorithm_implementations.h",
"algorithm_registry.cc",
"algorithm_registry.h",
+ "algorithms/aes.cc",
+ "algorithms/aes.h",
+ "algorithms/aes_cbc.cc",
+ "algorithms/aes_ctr.cc",
+ "algorithms/aes_gcm.cc",
+ "algorithms/aes_kw.cc",
+ "algorithms/asymmetric_key_util.cc",
+ "algorithms/asymmetric_key_util.h",
+ "algorithms/ec.cc",
+ "algorithms/ec.h",
+ "algorithms/ecdh.cc",
+ "algorithms/ecdsa.cc",
+ "algorithms/hkdf.cc",
+ "algorithms/hmac.cc",
+ "algorithms/pbkdf2.cc",
+ "algorithms/rsa.cc",
+ "algorithms/rsa.h",
+ "algorithms/rsa_oaep.cc",
+ "algorithms/rsa_pss.cc",
+ "algorithms/rsa_sign.cc",
+ "algorithms/rsa_sign.h",
+ "algorithms/rsa_ssa.cc",
+ "algorithms/secret_key_util.cc",
+ "algorithms/secret_key_util.h",
+ "algorithms/sha.cc",
+ "algorithms/util.cc",
+ "algorithms/util.h",
+ "blink_key_handle.cc",
+ "blink_key_handle.h",
"crypto_data.cc",
"crypto_data.h",
"generate_key_result.cc",
"generate_key_result.h",
"jwk.cc",
"jwk.h",
- "platform_crypto.h",
"status.cc",
"status.h",
"webcrypto_impl.cc",
"webcrypto_impl.h",
- "webcrypto_util.cc",
- "webcrypto_util.h",
]
deps = [
@@ -34,80 +61,31 @@ source_set("webcrypto") {
"//crypto:platform",
"//third_party/WebKit/public:blink",
]
-
- if (!use_openssl) {
- sources += [
- "nss/aes_algorithm_nss.cc",
- "nss/aes_algorithm_nss.h",
- "nss/aes_cbc_nss.cc",
- "nss/aes_gcm_nss.cc",
- "nss/aes_kw_nss.cc",
- "nss/hmac_nss.cc",
- "nss/key_nss.cc",
- "nss/key_nss.h",
- "nss/rsa_hashed_algorithm_nss.cc",
- "nss/rsa_hashed_algorithm_nss.h",
- "nss/rsa_oaep_nss.cc",
- "nss/rsa_ssa_nss.cc",
- "nss/sha_nss.cc",
- "nss/sym_key_nss.cc",
- "nss/sym_key_nss.h",
- "nss/util_nss.cc",
- "nss/util_nss.h",
- ]
- } else {
- sources += [
- "openssl/aes_algorithm_openssl.cc",
- "openssl/aes_algorithm_openssl.h",
- "openssl/aes_cbc_openssl.cc",
- "openssl/aes_ctr_openssl.cc",
- "openssl/aes_gcm_openssl.cc",
- "openssl/aes_kw_openssl.cc",
- "openssl/ec_algorithm_openssl.cc",
- "openssl/ec_algorithm_openssl.h",
- "openssl/ecdh_openssl.cc",
- "openssl/ecdsa_openssl.cc",
- "openssl/hkdf_openssl.cc",
- "openssl/hmac_openssl.cc",
- "openssl/key_openssl.cc",
- "openssl/key_openssl.h",
- "openssl/pbkdf2_openssl.cc",
- "openssl/rsa_hashed_algorithm_openssl.cc",
- "openssl/rsa_hashed_algorithm_openssl.h",
- "openssl/rsa_oaep_openssl.cc",
- "openssl/rsa_pss_openssl.cc",
- "openssl/rsa_sign_openssl.cc",
- "openssl/rsa_sign_openssl.h",
- "openssl/rsa_ssa_openssl.cc",
- "openssl/sha_openssl.cc",
- "openssl/util_openssl.cc",
- "openssl/util_openssl.h",
- ]
- }
}
source_set("unit_tests") {
testonly = true
sources = [
- "test/aes_cbc_unittest.cc",
- "test/aes_ctr_unittest.cc",
- "test/aes_gcm_unittest.cc",
- "test/aes_kw_unittest.cc",
- "test/ecdh_unittest.cc",
- "test/ecdsa_unittest.cc",
- "test/hmac_unittest.cc",
- "test/rsa_oaep_unittest.cc",
- "test/rsa_pss_unittest.cc",
- "test/rsa_ssa_unittest.cc",
- "test/sha_unittest.cc",
- "test/status_unittest.cc",
- "test/test_helpers.cc",
- "test/test_helpers.h",
+ "algorithms/aes_cbc_unittest.cc",
+ "algorithms/aes_ctr_unittest.cc",
+ "algorithms/aes_gcm_unittest.cc",
+ "algorithms/aes_kw_unittest.cc",
+ "algorithms/ecdh_unittest.cc",
+ "algorithms/ecdsa_unittest.cc",
+ "algorithms/hmac_unittest.cc",
+ "algorithms/rsa_oaep_unittest.cc",
+ "algorithms/rsa_pss_unittest.cc",
+ "algorithms/rsa_ssa_unittest.cc",
+ "algorithms/sha_unittest.cc",
+ "algorithms/test_helpers.cc",
+ "algorithms/test_helpers.h",
+ "status_unittest.cc",
]
deps = [
":webcrypto",
"//base/test:test_support",
+ "//components/test_runner:test_runner",
"//crypto",
"//crypto:platform",
"//testing/perf",
diff --git a/chromium/components/webcrypto/DEPS b/chromium/components/webcrypto/DEPS
index 5cdc8e79e93..14ca3e02e19 100644
--- a/chromium/components/webcrypto/DEPS
+++ b/chromium/components/webcrypto/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+components/test_runner",
"+crypto",
"+third_party/re2",
"+third_party/WebKit/public/platform",
diff --git a/chromium/components/webcrypto/algorithm_dispatch.cc b/chromium/components/webcrypto/algorithm_dispatch.cc
index ce29c91a3a6..63f529b0b00 100644
--- a/chromium/components/webcrypto/algorithm_dispatch.cc
+++ b/chromium/components/webcrypto/algorithm_dispatch.cc
@@ -6,12 +6,12 @@
#include "base/logging.h"
#include "components/webcrypto/algorithm_implementation.h"
+#include "components/webcrypto/algorithm_implementations.h"
#include "components/webcrypto/algorithm_registry.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
-#include "components/webcrypto/platform_crypto.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
+#include "crypto/openssl_util.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
namespace webcrypto {
@@ -65,7 +65,7 @@ Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
std::vector<uint8_t>* buffer) {
- if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt))
+ if (!key.keyUsageAllows(blink::WebCryptoKeyUsageEncrypt))
return Status::ErrorUnexpected();
return EncryptDontCheckUsage(algorithm, key, data, buffer);
}
@@ -74,7 +74,7 @@ Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
std::vector<uint8_t>* buffer) {
- if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt))
+ if (!key.keyUsageAllows(blink::WebCryptoKeyUsageDecrypt))
return Status::ErrorUnexpected();
return DecryptDontCheckKeyUsage(algorithm, key, data, buffer);
}
@@ -150,7 +150,7 @@ Status Sign(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
std::vector<uint8_t>* buffer) {
- if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign))
+ if (!key.keyUsageAllows(blink::WebCryptoKeyUsageSign))
return Status::ErrorUnexpected();
if (algorithm.id() != key.algorithm().id())
return Status::ErrorUnexpected();
@@ -168,7 +168,7 @@ Status Verify(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& signature,
const CryptoData& data,
bool* signature_match) {
- if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageVerify))
+ if (!key.keyUsageAllows(blink::WebCryptoKeyUsageVerify))
return Status::ErrorUnexpected();
if (algorithm.id() != key.algorithm().id())
return Status::ErrorUnexpected();
@@ -186,7 +186,7 @@ Status WrapKey(blink::WebCryptoKeyFormat format,
const blink::WebCryptoKey& wrapping_key,
const blink::WebCryptoAlgorithm& wrapping_algorithm,
std::vector<uint8_t>* buffer) {
- if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey))
+ if (!wrapping_key.keyUsageAllows(blink::WebCryptoKeyUsageWrapKey))
return Status::ErrorUnexpected();
std::vector<uint8_t> exported_data;
@@ -205,7 +205,7 @@ Status UnwrapKey(blink::WebCryptoKeyFormat format,
bool extractable,
blink::WebCryptoKeyUsageMask usages,
blink::WebCryptoKey* key) {
- if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey))
+ if (!wrapping_key.keyUsageAllows(blink::WebCryptoKeyUsageUnwrapKey))
return Status::ErrorUnexpected();
if (wrapping_algorithm.id() != wrapping_key.algorithm().id())
return Status::ErrorUnexpected();
@@ -230,7 +230,7 @@ Status UnwrapKey(blink::WebCryptoKeyFormat format,
// information about the plaintext of the encrypted key (for instance the JWK
// key_ops). As long as the ImportKey error messages don't describe actual
// key bytes however this should be OK. For more discussion see
- // http://crubg.com/372040
+ // http://crbug.com/372040
return ImportKey(format, CryptoData(buffer), algorithm, extractable, usages,
key);
}
@@ -239,7 +239,7 @@ Status DeriveBits(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& base_key,
unsigned int length_bits,
std::vector<uint8_t>* derived_bytes) {
- if (!KeyUsageAllows(base_key, blink::WebCryptoKeyUsageDeriveBits))
+ if (!base_key.keyUsageAllows(blink::WebCryptoKeyUsageDeriveBits))
return Status::ErrorUnexpected();
if (algorithm.id() != base_key.algorithm().id())
@@ -261,7 +261,7 @@ Status DeriveKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usages,
blink::WebCryptoKey* derived_key) {
- if (!KeyUsageAllows(base_key, blink::WebCryptoKeyUsageDeriveKey))
+ if (!base_key.keyUsageAllows(blink::WebCryptoKeyUsageDeriveKey))
return Status::ErrorUnexpected();
if (algorithm.id() != base_key.algorithm().id())
@@ -309,8 +309,8 @@ Status DeriveKey(const blink::WebCryptoAlgorithm& algorithm,
scoped_ptr<blink::WebCryptoDigestor> CreateDigestor(
blink::WebCryptoAlgorithmId algorithm) {
- PlatformInit();
- return CreatePlatformDigestor(algorithm);
+ crypto::EnsureOpenSSLInit();
+ return CreateDigestorImplementation(algorithm);
}
bool SerializeKeyForClone(const blink::WebCryptoKey& key,
diff --git a/chromium/components/webcrypto/algorithm_implementation.cc b/chromium/components/webcrypto/algorithm_implementation.cc
index 1d98b4427ba..8db7482ce73 100644
--- a/chromium/components/webcrypto/algorithm_implementation.cc
+++ b/chromium/components/webcrypto/algorithm_implementation.cc
@@ -4,6 +4,7 @@
#include "components/webcrypto/algorithm_implementation.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/status.h"
namespace webcrypto {
@@ -181,7 +182,8 @@ Status AlgorithmImplementation::ExportKeyJwk(
Status AlgorithmImplementation::SerializeKeyForClone(
const blink::WebCryptoKey& key,
blink::WebVector<uint8_t>* key_data) const {
- return Status::ErrorUnsupported();
+ *key_data = GetSerializedKeyData(key);
+ return Status::Success();
}
Status AlgorithmImplementation::DeserializeKeyForClone(
diff --git a/chromium/components/webcrypto/algorithm_implementation.h b/chromium/components/webcrypto/algorithm_implementation.h
index bbe42146dff..993c168d5f7 100644
--- a/chromium/components/webcrypto/algorithm_implementation.h
+++ b/chromium/components/webcrypto/algorithm_implementation.h
@@ -36,6 +36,10 @@ class Status;
// * The key usages have already been verified. In fact in the case of calls
// to Encrypt()/Decrypt() the corresponding key usages may not be present
// (when wrapping/unwrapping).
+//
+// An AlgorithmImplementation can also assume that
+// crypto::EnsureOpenSSLInit() will be called before any of its
+// methods are invoked (except the constructor).
class AlgorithmImplementation {
public:
virtual ~AlgorithmImplementation();
@@ -204,9 +208,11 @@ class AlgorithmImplementation {
//
// Tests to verify structured cloning are available in:
// LayoutTests/crypto/clone-*.html
- virtual Status SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const;
+
+ // Note that SerializeKeyForClone() is not virtual because all
+ // implementations end up doing the same thing.
+ Status SerializeKeyForClone(const blink::WebCryptoKey& key,
+ blink::WebVector<uint8_t>* key_data) const;
virtual Status DeserializeKeyForClone(
const blink::WebCryptoKeyAlgorithm& algorithm,
diff --git a/chromium/components/webcrypto/algorithm_implementations.h b/chromium/components/webcrypto/algorithm_implementations.h
new file mode 100644
index 00000000000..a6bea01f63f
--- /dev/null
+++ b/chromium/components/webcrypto/algorithm_implementations.h
@@ -0,0 +1,35 @@
+// 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_WEBCRYPTO_ALGORITHM_IMPLEMENTATIONS_H_
+#define COMPONENTS_WEBCRYPTO_ALGORITHM_IMPLEMENTATIONS_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "third_party/WebKit/public/platform/WebCrypto.h"
+
+// The definitions for these functions live in the algorithms/ directory.
+namespace webcrypto {
+
+class AlgorithmImplementation;
+
+scoped_ptr<blink::WebCryptoDigestor> CreateDigestorImplementation(
+ blink::WebCryptoAlgorithmId algorithm);
+
+scoped_ptr<AlgorithmImplementation> CreateShaImplementation();
+scoped_ptr<AlgorithmImplementation> CreateAesCbcImplementation();
+scoped_ptr<AlgorithmImplementation> CreateAesCtrImplementation();
+scoped_ptr<AlgorithmImplementation> CreateAesGcmImplementation();
+scoped_ptr<AlgorithmImplementation> CreateAesKwImplementation();
+scoped_ptr<AlgorithmImplementation> CreateHmacImplementation();
+scoped_ptr<AlgorithmImplementation> CreateRsaOaepImplementation();
+scoped_ptr<AlgorithmImplementation> CreateRsaSsaImplementation();
+scoped_ptr<AlgorithmImplementation> CreateRsaPssImplementation();
+scoped_ptr<AlgorithmImplementation> CreateEcdsaImplementation();
+scoped_ptr<AlgorithmImplementation> CreateEcdhImplementation();
+scoped_ptr<AlgorithmImplementation> CreateHkdfImplementation();
+scoped_ptr<AlgorithmImplementation> CreatePbkdf2Implementation();
+
+} // namespace webcrypto
+
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHM_IMPLEMENTATIONS_H_
diff --git a/chromium/components/webcrypto/algorithm_registry.cc b/chromium/components/webcrypto/algorithm_registry.cc
index ea4799e70e9..b82737e732b 100644
--- a/chromium/components/webcrypto/algorithm_registry.cc
+++ b/chromium/components/webcrypto/algorithm_registry.cc
@@ -6,8 +6,9 @@
#include "base/lazy_instance.h"
#include "components/webcrypto/algorithm_implementation.h"
-#include "components/webcrypto/platform_crypto.h"
+#include "components/webcrypto/algorithm_implementations.h"
#include "components/webcrypto/status.h"
+#include "crypto/openssl_util.h"
namespace webcrypto {
@@ -17,20 +18,20 @@ namespace {
class AlgorithmRegistry {
public:
AlgorithmRegistry()
- : sha_(CreatePlatformShaImplementation()),
- aes_gcm_(CreatePlatformAesGcmImplementation()),
- aes_cbc_(CreatePlatformAesCbcImplementation()),
- aes_ctr_(CreatePlatformAesCtrImplementation()),
- aes_kw_(CreatePlatformAesKwImplementation()),
- hmac_(CreatePlatformHmacImplementation()),
- rsa_ssa_(CreatePlatformRsaSsaImplementation()),
- rsa_oaep_(CreatePlatformRsaOaepImplementation()),
- rsa_pss_(CreatePlatformRsaPssImplementation()),
- ecdsa_(CreatePlatformEcdsaImplementation()),
- ecdh_(CreatePlatformEcdhImplementation()),
- hkdf_(CreatePlatformHkdfImplementation()),
- pbkdf2_(CreatePlatformPbkdf2Implementation()) {
- PlatformInit();
+ : sha_(CreateShaImplementation()),
+ aes_gcm_(CreateAesGcmImplementation()),
+ aes_cbc_(CreateAesCbcImplementation()),
+ aes_ctr_(CreateAesCtrImplementation()),
+ aes_kw_(CreateAesKwImplementation()),
+ hmac_(CreateHmacImplementation()),
+ rsa_ssa_(CreateRsaSsaImplementation()),
+ rsa_oaep_(CreateRsaOaepImplementation()),
+ rsa_pss_(CreateRsaPssImplementation()),
+ ecdsa_(CreateEcdsaImplementation()),
+ ecdh_(CreateEcdhImplementation()),
+ hkdf_(CreateHkdfImplementation()),
+ pbkdf2_(CreatePbkdf2Implementation()) {
+ crypto::EnsureOpenSSLInit();
}
const AlgorithmImplementation* GetAlgorithm(
diff --git a/chromium/components/webcrypto/openssl/aes_algorithm_openssl.cc b/chromium/components/webcrypto/algorithms/aes.cc
index 05e30c5bfd5..09dbfd45c49 100644
--- a/chromium/components/webcrypto/openssl/aes_algorithm_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/aes.cc
@@ -2,19 +2,44 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/webcrypto/openssl/aes_algorithm_openssl.h"
+#include "components/webcrypto/algorithms/aes.h"
#include "base/logging.h"
+#include "components/webcrypto/algorithms/secret_key_util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
namespace webcrypto {
+namespace {
+
+// Creates an AES algorithm name for the given key size (in bytes). For
+// instance "A128CBC" is the result of suffix="CBC", keylen_bytes=16.
+std::string MakeJwkAesAlgorithmName(const std::string& suffix,
+ size_t keylen_bytes) {
+ if (keylen_bytes == 16)
+ return std::string("A128") + suffix;
+ if (keylen_bytes == 24)
+ return std::string("A192") + suffix;
+ if (keylen_bytes == 32)
+ return std::string("A256") + suffix;
+ return std::string();
+}
+
+// Synthesizes an import algorithm given a key algorithm, so that
+// deserialization can re-use the ImportKey*() methods.
+blink::WebCryptoAlgorithm SynthesizeImportAlgorithmForClone(
+ const blink::WebCryptoKeyAlgorithm& algorithm) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(algorithm.id(),
+ nullptr);
+}
+
+} // namespace
+
AesAlgorithm::AesAlgorithm(blink::WebCryptoKeyUsageMask all_key_usages,
const std::string& jwk_suffix)
: all_key_usages_(all_key_usages), jwk_suffix_(jwk_suffix) {
@@ -32,14 +57,18 @@ Status AesAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usages,
GenerateKeyResult* result) const {
- Status status = CheckKeyCreationUsages(all_key_usages_, usages, false);
+ Status status = CheckSecretKeyCreationUsages(all_key_usages_, usages);
if (status.IsError())
return status;
- unsigned int keylen_bits;
- status = GetAesKeyGenLengthInBits(algorithm.aesKeyGenParams(), &keylen_bits);
- if (status.IsError())
- return status;
+ unsigned int keylen_bits = algorithm.aesKeyGenParams()->lengthBits();
+
+ // 192-bit AES is intentionally unsupported (http://crbug.com/533699).
+ if (keylen_bits == 192)
+ return Status::ErrorAes192BitUnsupported();
+
+ if (keylen_bits != 128 && keylen_bits != 256)
+ return Status::ErrorGenerateAesKeyLength();
return GenerateWebCryptoSecretKey(
blink::WebCryptoKeyAlgorithm::createAes(algorithm.id(), keylen_bits),
@@ -52,7 +81,7 @@ Status AesAlgorithm::VerifyKeyUsagesBeforeImportKey(
switch (format) {
case blink::WebCryptoKeyFormatRaw:
case blink::WebCryptoKeyFormatJwk:
- return CheckKeyCreationUsages(all_key_usages_, usages, false);
+ return CheckSecretKeyCreationUsages(all_key_usages_, usages);
default:
return Status::ErrorUnsupportedImportKeyFormat();
}
@@ -64,9 +93,13 @@ Status AesAlgorithm::ImportKeyRaw(const CryptoData& key_data,
blink::WebCryptoKeyUsageMask usages,
blink::WebCryptoKey* key) const {
const unsigned int keylen_bytes = key_data.byte_length();
- Status status = VerifyAesKeyLengthForImport(keylen_bytes);
- if (status.IsError())
- return status;
+
+ // 192-bit AES is intentionally unsupported (http://crbug.com/533699).
+ if (keylen_bytes == 24)
+ return Status::ErrorAes192BitUnsupported();
+
+ if (keylen_bytes != 16 && keylen_bytes != 32)
+ return Status::ErrorImportAesKeyLength();
// No possibility of overflow.
unsigned int keylen_bits = keylen_bytes * 8;
@@ -83,25 +116,46 @@ Status AesAlgorithm::ImportKeyJwk(const CryptoData& key_data,
blink::WebCryptoKeyUsageMask usages,
blink::WebCryptoKey* key) const {
std::vector<uint8_t> raw_data;
- Status status = ReadAesSecretKeyJwk(key_data, jwk_suffix_, extractable,
- usages, &raw_data);
+ JwkReader jwk;
+ Status status = ReadSecretKeyNoExpectedAlgJwk(key_data, extractable, usages,
+ &raw_data, &jwk);
+ if (status.IsError())
+ return status;
+
+ bool has_jwk_alg;
+ std::string jwk_alg;
+ status = jwk.GetAlg(&jwk_alg, &has_jwk_alg);
if (status.IsError())
return status;
+ if (has_jwk_alg) {
+ std::string expected_algorithm_name =
+ MakeJwkAesAlgorithmName(jwk_suffix_, raw_data.size());
+
+ if (jwk_alg != expected_algorithm_name) {
+ // Give a different error message if the key length was wrong.
+ if (jwk_alg == MakeJwkAesAlgorithmName(jwk_suffix_, 16) ||
+ jwk_alg == MakeJwkAesAlgorithmName(jwk_suffix_, 24) ||
+ jwk_alg == MakeJwkAesAlgorithmName(jwk_suffix_, 32)) {
+ return Status::ErrorJwkIncorrectKeyLength();
+ }
+ return Status::ErrorJwkAlgorithmInconsistent();
+ }
+ }
+
return ImportKeyRaw(CryptoData(raw_data), algorithm, extractable, usages,
key);
}
Status AesAlgorithm::ExportKeyRaw(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const {
- *buffer = SymKeyOpenSsl::Cast(key)->raw_key_data();
+ *buffer = GetSymmetricKeyData(key);
return Status::Success();
}
Status AesAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const {
- const std::vector<uint8_t>& raw_data =
- SymKeyOpenSsl::Cast(key)->raw_key_data();
+ const std::vector<uint8_t>& raw_data = GetSymmetricKeyData(key);
WriteSecretKeyJwk(CryptoData(raw_data),
MakeJwkAesAlgorithmName(jwk_suffix_, raw_data.size()),
@@ -110,13 +164,6 @@ Status AesAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key,
return Status::Success();
}
-Status AesAlgorithm::SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const {
- key_data->assign(SymKeyOpenSsl::Cast(key)->serialized_key_data());
- return Status::Success();
-}
-
Status AesAlgorithm::DeserializeKeyForClone(
const blink::WebCryptoKeyAlgorithm& algorithm,
blink::WebCryptoKeyType type,
@@ -124,15 +171,25 @@ Status AesAlgorithm::DeserializeKeyForClone(
blink::WebCryptoKeyUsageMask usages,
const CryptoData& key_data,
blink::WebCryptoKey* key) const {
- return ImportKeyRaw(key_data, CreateAlgorithm(algorithm.id()), extractable,
- usages, key);
+ return ImportKeyRaw(key_data, SynthesizeImportAlgorithmForClone(algorithm),
+ extractable, usages, key);
}
Status AesAlgorithm::GetKeyLength(
const blink::WebCryptoAlgorithm& key_length_algorithm,
bool* has_length_bits,
unsigned int* length_bits) const {
- return GetAesKeyLength(key_length_algorithm, has_length_bits, length_bits);
+ *has_length_bits = true;
+ *length_bits = key_length_algorithm.aesDerivedKeyParams()->lengthBits();
+
+ if (*length_bits == 128 || *length_bits == 256)
+ return Status::Success();
+
+ // 192-bit AES is intentionally unsupported (http://crbug.com/533699).
+ if (*length_bits == 192)
+ return Status::ErrorAes192BitUnsupported();
+
+ return Status::ErrorGetAesKeyLength();
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/aes_algorithm_openssl.h b/chromium/components/webcrypto/algorithms/aes.h
index fd87bacd0ec..62cc3b1e406 100644
--- a/chromium/components/webcrypto/openssl/aes_algorithm_openssl.h
+++ b/chromium/components/webcrypto/algorithms/aes.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_WEBCRYPTO_OPENSSL_AES_ALGORITHM_OPENSSL_H_
-#define COMPONENTS_WEBCRYPTO_OPENSSL_AES_ALGORITHM_OPENSSL_H_
+#ifndef COMPONENTS_WEBCRYPTO_ALGORITHMS_AES_H_
+#define COMPONENTS_WEBCRYPTO_ALGORITHMS_AES_H_
#include "components/webcrypto/algorithm_implementation.h"
@@ -53,10 +53,6 @@ class AesAlgorithm : public AlgorithmImplementation {
Status ExportKeyJwk(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const override;
- Status SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const override;
-
Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
blink::WebCryptoKeyType type,
bool extractable,
@@ -75,4 +71,4 @@ class AesAlgorithm : public AlgorithmImplementation {
} // namespace webcrypto
-#endif // COMPONENTS_WEBCRYPTO_OPENSSL_AES_ALGORITHM_OPENSSL_H_
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_AES_H_
diff --git a/chromium/components/webcrypto/openssl/aes_cbc_openssl.cc b/chromium/components/webcrypto/algorithms/aes_cbc.cc
index 4d1ece247df..0d9c88ef6f9 100644
--- a/chromium/components/webcrypto/openssl/aes_cbc_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/aes_cbc.cc
@@ -8,12 +8,11 @@
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/aes.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/openssl/aes_algorithm_openssl.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -23,7 +22,7 @@ namespace webcrypto {
namespace {
const EVP_CIPHER* GetAESCipherByKeyLength(size_t key_length_bytes) {
- // BoringSSL does not support 192-bit AES keys.
+ // 192-bit AES is intentionally unsupported (http://crbug.com/533699).
switch (key_length_bytes) {
case 16:
return EVP_aes_128_cbc();
@@ -42,8 +41,7 @@ Status AesCbcEncryptDecrypt(EncryptOrDecrypt cipher_operation,
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
const blink::WebCryptoAesCbcParams* params = algorithm.aesCbcParams();
- const std::vector<uint8_t>& raw_key =
- SymKeyOpenSsl::Cast(key)->raw_key_data();
+ const std::vector<uint8_t>& raw_key = GetSymmetricKeyData(key);
if (params->iv().size() != 16)
return Status::ErrorIncorrectSizeAesCbcIv();
@@ -122,8 +120,8 @@ class AesCbcImplementation : public AesAlgorithm {
} // namespace
-AlgorithmImplementation* CreatePlatformAesCbcImplementation() {
- return new AesCbcImplementation;
+scoped_ptr<AlgorithmImplementation> CreateAesCbcImplementation() {
+ return make_scoped_ptr(new AesCbcImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/aes_cbc_unittest.cc b/chromium/components/webcrypto/algorithms/aes_cbc_unittest.cc
new file mode 100644
index 00000000000..44f07ea0bce
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/aes_cbc_unittest.cc
@@ -0,0 +1,568 @@
+// 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 "base/stl_util.h"
+#include "base/values.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+// Creates an AES-CBC algorithm.
+blink::WebCryptoAlgorithm CreateAesCbcAlgorithm(
+ const std::vector<uint8_t>& iv) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdAesCbc,
+ new blink::WebCryptoAesCbcParams(vector_as_array(&iv),
+ static_cast<unsigned int>(iv.size())));
+}
+
+blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm(
+ unsigned short key_length_bits) {
+ return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc,
+ key_length_bits);
+}
+
+blink::WebCryptoKey GetTestAesCbcKey() {
+ const std::string key_hex = "2b7e151628aed2a6abf7158809cf4f3c";
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw(
+ HexStringToBytes(key_hex),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
+
+ // Verify exported raw key is identical to the imported data
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ EXPECT_BYTES_EQ_HEX(key_hex, raw_key);
+ return key;
+}
+
+class WebCryptoAesCbcTest : public WebCryptoTestBase {};
+
+TEST_F(WebCryptoAesCbcTest, InputTooLarge) {
+ std::vector<uint8_t> output;
+
+ std::vector<uint8_t> iv(16);
+
+ // Give an input that is too large. It would cause integer overflow when
+ // narrowing the ciphertext size to an int, since OpenSSL operates on signed
+ // int lengths NOT unsigned.
+ //
+ // Pretend the input is large. Don't pass data pointer as NULL in case that
+ // is special cased; the implementation shouldn't actually dereference the
+ // data.
+ CryptoData input(&iv[0], INT_MAX - 3);
+
+ EXPECT_EQ(
+ Status::ErrorDataTooLarge(),
+ Encrypt(CreateAesCbcAlgorithm(iv), GetTestAesCbcKey(), input, &output));
+ EXPECT_EQ(
+ Status::ErrorDataTooLarge(),
+ Decrypt(CreateAesCbcAlgorithm(iv), GetTestAesCbcKey(), input, &output));
+}
+
+TEST_F(WebCryptoAesCbcTest, ExportKeyUnsupportedFormat) {
+ std::vector<uint8_t> output;
+
+ // Fail exporting the key in SPKI and PKCS#8 formats (not allowed for secret
+ // keys).
+ EXPECT_EQ(
+ Status::ErrorUnsupportedExportKeyFormat(),
+ ExportKey(blink::WebCryptoKeyFormatSpki, GetTestAesCbcKey(), &output));
+ EXPECT_EQ(
+ Status::ErrorUnsupportedExportKeyFormat(),
+ ExportKey(blink::WebCryptoKeyFormatPkcs8, GetTestAesCbcKey(), &output));
+}
+
+// Tests importing of keys (in a variety of formats), errors during import,
+// encryption, and decryption, using known answers.
+TEST_F(WebCryptoAesCbcTest, KnownAnswerEncryptDecrypt) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("aes_cbc.json", &tests));
+
+ 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));
+
+ blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
+ std::vector<uint8_t> key_data =
+ GetKeyDataFromJsonTestCase(test, key_format);
+ std::string import_error = "Success";
+ test->GetString("import_error", &import_error);
+
+ // Import the key.
+ blink::WebCryptoKey key;
+ Status status = ImportKey(
+ key_format, CryptoData(key_data),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true,
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
+ &key);
+ ASSERT_EQ(import_error, StatusToString(status));
+ if (status.IsError())
+ continue;
+
+ // Test encryption.
+ if (test->HasKey("plain_text")) {
+ std::vector<uint8_t> test_plain_text =
+ GetBytesFromHexString(test, "plain_text");
+
+ std::vector<uint8_t> test_iv = GetBytesFromHexString(test, "iv");
+
+ std::string encrypt_error = "Success";
+ test->GetString("encrypt_error", &encrypt_error);
+
+ std::vector<uint8_t> output;
+ status = Encrypt(CreateAesCbcAlgorithm(test_iv), key,
+ CryptoData(test_plain_text), &output);
+ ASSERT_EQ(encrypt_error, StatusToString(status));
+ if (status.IsError())
+ continue;
+
+ std::vector<uint8_t> test_cipher_text =
+ GetBytesFromHexString(test, "cipher_text");
+
+ EXPECT_BYTES_EQ(test_cipher_text, output);
+ }
+
+ // Test decryption.
+ if (test->HasKey("cipher_text")) {
+ std::vector<uint8_t> test_cipher_text =
+ GetBytesFromHexString(test, "cipher_text");
+
+ std::vector<uint8_t> test_iv = GetBytesFromHexString(test, "iv");
+
+ std::string decrypt_error = "Success";
+ test->GetString("decrypt_error", &decrypt_error);
+
+ std::vector<uint8_t> output;
+ status = Decrypt(CreateAesCbcAlgorithm(test_iv), key,
+ CryptoData(test_cipher_text), &output);
+ ASSERT_EQ(decrypt_error, StatusToString(status));
+ if (status.IsError())
+ continue;
+
+ std::vector<uint8_t> test_plain_text =
+ GetBytesFromHexString(test, "plain_text");
+
+ EXPECT_BYTES_EQ(test_plain_text, output);
+ }
+ }
+}
+
+// TODO(eroman): Do this same test for AES-GCM, AES-KW, AES-CTR ?
+TEST_F(WebCryptoAesCbcTest, GenerateKeyIsRandom) {
+ // Check key generation for each allowed key length.
+ std::vector<blink::WebCryptoAlgorithm> algorithm;
+ const unsigned short kKeyLength[] = {128, 256};
+ for (size_t key_length_i = 0; key_length_i < arraysize(kKeyLength);
+ ++key_length_i) {
+ blink::WebCryptoKey key;
+
+ std::vector<std::vector<uint8_t>> keys;
+ std::vector<uint8_t> key_bytes;
+
+ // Generate a small sample of keys.
+ for (int j = 0; j < 16; ++j) {
+ ASSERT_EQ(Status::Success(),
+ GenerateSecretKey(
+ CreateAesCbcKeyGenAlgorithm(kKeyLength[key_length_i]), true,
+ blink::WebCryptoKeyUsageEncrypt, &key));
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_bytes));
+ EXPECT_EQ(key_bytes.size() * 8,
+ key.algorithm().aesParams()->lengthBits());
+ keys.push_back(key_bytes);
+ }
+ // Ensure all entries in the key sample set are unique. This is a simplistic
+ // estimate of whether the generated keys appear random.
+ EXPECT_FALSE(CopiesExist(keys));
+ }
+}
+
+TEST_F(WebCryptoAesCbcTest, GenerateKeyBadLength) {
+ const unsigned short kKeyLen[] = {0, 127, 257};
+ blink::WebCryptoKey key;
+ for (size_t i = 0; i < arraysize(kKeyLen); ++i) {
+ SCOPED_TRACE(i);
+ EXPECT_EQ(Status::ErrorGenerateAesKeyLength(),
+ GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(kKeyLen[i]), true,
+ blink::WebCryptoKeyUsageEncrypt, &key));
+ }
+}
+
+TEST_F(WebCryptoAesCbcTest, ImportKeyEmptyUsage) {
+ blink::WebCryptoKey key;
+ ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(std::vector<uint8_t>(16)),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true,
+ 0, &key));
+}
+
+// If key_ops is specified but empty, no key usages are allowed for the key.
+TEST_F(WebCryptoAesCbcTest, ImportKeyJwkEmptyKeyOps) {
+ blink::WebCryptoKey key;
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetBoolean("ext", false);
+ dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
+ dict.Set("key_ops", new base::ListValue); // Takes ownership.
+
+ // The JWK does not contain encrypt usages.
+ EXPECT_EQ(Status::ErrorJwkKeyopsInconsistent(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageEncrypt, &key));
+
+ // The JWK does not contain sign usage (nor is it applicable).
+ EXPECT_EQ(Status::ErrorCreateKeyBadUsages(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageSign, &key));
+}
+
+// If key_ops is missing, then any key usages can be specified.
+TEST_F(WebCryptoAesCbcTest, ImportKeyJwkNoKeyOps) {
+ blink::WebCryptoKey key;
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
+
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageEncrypt, &key));
+
+ EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages());
+
+ // The JWK does not contain sign usage (nor is it applicable).
+ EXPECT_EQ(Status::ErrorCreateKeyBadUsages(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageVerify, &key));
+}
+
+TEST_F(WebCryptoAesCbcTest, ImportKeyJwkKeyOpsEncryptDecrypt) {
+ blink::WebCryptoKey key;
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
+ base::ListValue* key_ops = new base::ListValue;
+ dict.Set("key_ops", key_ops); // Takes ownership.
+
+ key_ops->AppendString("encrypt");
+
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageEncrypt, &key));
+
+ EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages());
+
+ key_ops->AppendString("decrypt");
+
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageDecrypt, &key));
+
+ EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt, key.usages());
+
+ EXPECT_EQ(
+ Status::Success(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt,
+ &key));
+
+ EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
+ key.usages());
+}
+
+// Test failure if input usage is NOT a strict subset of the JWK usage.
+TEST_F(WebCryptoAesCbcTest, ImportKeyJwkKeyOpsNotSuperset) {
+ blink::WebCryptoKey key;
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
+ base::ListValue* key_ops = new base::ListValue;
+ dict.Set("key_ops", key_ops); // Takes ownership.
+
+ key_ops->AppendString("encrypt");
+
+ EXPECT_EQ(
+ Status::ErrorJwkKeyopsInconsistent(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
+ &key));
+}
+
+TEST_F(WebCryptoAesCbcTest, ImportKeyJwkUseEnc) {
+ blink::WebCryptoKey key;
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
+
+ // Test JWK composite use 'enc' usage
+ dict.SetString("alg", "A128CBC");
+ dict.SetString("use", "enc");
+ EXPECT_EQ(
+ Status::Success(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt |
+ blink::WebCryptoKeyUsageWrapKey |
+ blink::WebCryptoKeyUsageUnwrapKey,
+ &key));
+ EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt |
+ blink::WebCryptoKeyUsageWrapKey |
+ blink::WebCryptoKeyUsageUnwrapKey,
+ key.usages());
+}
+
+TEST_F(WebCryptoAesCbcTest, ImportJwkInvalidJson) {
+ blink::WebCryptoKey key;
+ // Fail on empty JSON.
+ EXPECT_EQ(
+ Status::ErrorJwkNotDictionary(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(MakeJsonVector("")),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageEncrypt, &key));
+
+ // Fail on invalid JSON.
+ const std::vector<uint8_t> bad_json_vec = MakeJsonVector(
+ "{"
+ "\"kty\" : \"oct\","
+ "\"alg\" : \"HS256\","
+ "\"use\" : ");
+ EXPECT_EQ(Status::ErrorJwkNotDictionary(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(bad_json_vec),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageEncrypt, &key));
+}
+
+// Fail on inconsistent key_ops - asking for "encrypt" however JWK contains
+// only "foo".
+TEST_F(WebCryptoAesCbcTest, ImportJwkKeyOpsLacksUsages) {
+ blink::WebCryptoKey key;
+
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
+
+ base::ListValue* key_ops = new base::ListValue;
+ // Note: the following call makes dict assume ownership of key_ops.
+ dict.Set("key_ops", key_ops);
+ key_ops->AppendString("foo");
+ EXPECT_EQ(Status::ErrorJwkKeyopsInconsistent(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
+ blink::WebCryptoKeyUsageEncrypt, &key));
+}
+
+TEST_F(WebCryptoAesCbcTest, ImportExportJwk) {
+ const blink::WebCryptoAlgorithm algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
+
+ // AES-CBC 128
+ ImportExportJwkSymmetricKey(
+ 128, algorithm,
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
+ "A128CBC");
+
+ // AES-CBC 256
+ ImportExportJwkSymmetricKey(256, algorithm, blink::WebCryptoKeyUsageDecrypt,
+ "A256CBC");
+
+ // Large usage value
+ ImportExportJwkSymmetricKey(
+ 256, algorithm,
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt |
+ blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey,
+ "A256CBC");
+}
+
+// 192-bit AES is intentionally unsupported (http://crbug.com/533699).
+TEST_F(WebCryptoAesCbcTest, GenerateAesCbc192) {
+ blink::WebCryptoKey key;
+ Status status = GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(192), true,
+ blink::WebCryptoKeyUsageEncrypt, &key);
+ ASSERT_EQ(Status::ErrorAes192BitUnsupported(), status);
+}
+
+// 192-bit AES is intentionally unsupported (http://crbug.com/533699).
+TEST_F(WebCryptoAesCbcTest, UnwrapAesCbc192) {
+ std::vector<uint8_t> wrapping_key_data(16, 0);
+ std::vector<uint8_t> wrapped_key = HexStringToBytes(
+ "1A07ACAB6C906E50883173C29441DB1DE91D34F45C435B5F99C822867FB3956F");
+
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+ wrapping_key_data, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
+ blink::WebCryptoKeyUsageUnwrapKey);
+
+ blink::WebCryptoKey unwrapped_key;
+ ASSERT_EQ(
+ Status::ErrorAes192BitUnsupported(),
+ UnwrapKey(blink::WebCryptoKeyFormatRaw, CryptoData(wrapped_key),
+ wrapping_key, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true,
+ blink::WebCryptoKeyUsageEncrypt, &unwrapped_key));
+}
+
+// Try importing an AES-CBC key with unsupported key usages using raw
+// format. AES-CBC keys support the following usages:
+// 'encrypt', 'decrypt', 'wrapKey', 'unwrapKey'
+TEST_F(WebCryptoAesCbcTest, ImportKeyBadUsage_Raw) {
+ const blink::WebCryptoAlgorithm algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
+
+ blink::WebCryptoKeyUsageMask bad_usages[] = {
+ blink::WebCryptoKeyUsageSign,
+ blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageDecrypt,
+ blink::WebCryptoKeyUsageDeriveBits,
+ blink::WebCryptoKeyUsageUnwrapKey | blink::WebCryptoKeyUsageVerify,
+ };
+
+ std::vector<uint8_t> key_bytes(16);
+
+ for (size_t i = 0; i < arraysize(bad_usages); ++i) {
+ SCOPED_TRACE(i);
+
+ blink::WebCryptoKey key;
+ ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
+ ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(key_bytes),
+ algorithm, true, bad_usages[i], &key));
+ }
+}
+
+// Generate an AES-CBC key with invalid usages. AES-CBC supports:
+// 'encrypt', 'decrypt', 'wrapKey', 'unwrapKey'
+TEST_F(WebCryptoAesCbcTest, GenerateKeyBadUsages) {
+ blink::WebCryptoKeyUsageMask bad_usages[] = {
+ blink::WebCryptoKeyUsageSign,
+ blink::WebCryptoKeyUsageVerify,
+ blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageVerify,
+ };
+
+ for (size_t i = 0; i < arraysize(bad_usages); ++i) {
+ SCOPED_TRACE(i);
+
+ blink::WebCryptoKey key;
+
+ ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
+ GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(128), true,
+ bad_usages[i], &key));
+ }
+}
+
+// Generate an AES-CBC key with no usages.
+TEST_F(WebCryptoAesCbcTest, GenerateKeyEmptyUsages) {
+ blink::WebCryptoKey key;
+
+ ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(128), true, 0, &key));
+}
+
+// Generate an AES-CBC key and an RSA key pair. Use the AES-CBC key to wrap the
+// key pair (using SPKI format for public key, PKCS8 format for private key).
+// Then unwrap the wrapped key pair and verify that the key data is the same.
+TEST_F(WebCryptoAesCbcTest, WrapUnwrapRoundtripSpkiPkcs8) {
+ // Generate the wrapping key.
+ blink::WebCryptoKey wrapping_key;
+ ASSERT_EQ(Status::Success(),
+ GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(128), true,
+ blink::WebCryptoKeyUsageWrapKey |
+ blink::WebCryptoKeyUsageUnwrapKey,
+ &wrapping_key));
+
+ // Generate an RSA key pair to be wrapped.
+ const unsigned int modulus_length = 256;
+ const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+ ASSERT_EQ(Status::Success(),
+ GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256,
+ modulus_length, public_exponent),
+ true, blink::WebCryptoKeyUsageSign, &public_key,
+ &private_key));
+
+ // Export key pair as SPKI + PKCS8
+ std::vector<uint8_t> public_key_spki;
+ ASSERT_EQ(Status::Success(), ExportKey(blink::WebCryptoKeyFormatSpki,
+ public_key, &public_key_spki));
+
+ std::vector<uint8_t> private_key_pkcs8;
+ ASSERT_EQ(Status::Success(), ExportKey(blink::WebCryptoKeyFormatPkcs8,
+ private_key, &private_key_pkcs8));
+
+ // Wrap the key pair.
+ blink::WebCryptoAlgorithm wrap_algorithm =
+ CreateAesCbcAlgorithm(std::vector<uint8_t>(16, 0));
+
+ std::vector<uint8_t> wrapped_public_key;
+ ASSERT_EQ(Status::Success(),
+ WrapKey(blink::WebCryptoKeyFormatSpki, public_key, wrapping_key,
+ wrap_algorithm, &wrapped_public_key));
+
+ std::vector<uint8_t> wrapped_private_key;
+ ASSERT_EQ(Status::Success(),
+ WrapKey(blink::WebCryptoKeyFormatPkcs8, private_key, wrapping_key,
+ wrap_algorithm, &wrapped_private_key));
+
+ // Unwrap the key pair.
+ blink::WebCryptoAlgorithm rsa_import_algorithm =
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256);
+
+ blink::WebCryptoKey unwrapped_public_key;
+
+ ASSERT_EQ(
+ Status::Success(),
+ UnwrapKey(blink::WebCryptoKeyFormatSpki, CryptoData(wrapped_public_key),
+ wrapping_key, wrap_algorithm, rsa_import_algorithm, true,
+ blink::WebCryptoKeyUsageVerify, &unwrapped_public_key));
+
+ blink::WebCryptoKey unwrapped_private_key;
+
+ ASSERT_EQ(
+ Status::Success(),
+ UnwrapKey(blink::WebCryptoKeyFormatPkcs8, CryptoData(wrapped_private_key),
+ wrapping_key, wrap_algorithm, rsa_import_algorithm, true,
+ blink::WebCryptoKeyUsageSign, &unwrapped_private_key));
+
+ // Export unwrapped key pair as SPKI + PKCS8
+ std::vector<uint8_t> unwrapped_public_key_spki;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatSpki, unwrapped_public_key,
+ &unwrapped_public_key_spki));
+
+ std::vector<uint8_t> unwrapped_private_key_pkcs8;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatPkcs8, unwrapped_private_key,
+ &unwrapped_private_key_pkcs8));
+
+ EXPECT_EQ(public_key_spki, unwrapped_public_key_spki);
+ EXPECT_EQ(private_key_pkcs8, unwrapped_private_key_pkcs8);
+
+ EXPECT_NE(public_key_spki, wrapped_public_key);
+ EXPECT_NE(private_key_pkcs8, wrapped_private_key);
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/aes_ctr_openssl.cc b/chromium/components/webcrypto/algorithms/aes_ctr.cc
index 26363f72b55..f4c16b63d75 100644
--- a/chromium/components/webcrypto/openssl/aes_ctr_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/aes_ctr.cc
@@ -9,12 +9,11 @@
#include "base/macros.h"
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/aes.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/openssl/aes_algorithm_openssl.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -24,7 +23,7 @@ namespace webcrypto {
namespace {
const EVP_CIPHER* GetAESCipherByKeyLength(size_t key_length_bytes) {
- // BoringSSL does not support 192-bit AES keys.
+ // 192-bit AES is intentionally unsupported (http://crbug.com/533699).
switch (key_length_bytes) {
case 16:
return EVP_aes_128_ctr();
@@ -149,8 +148,7 @@ Status AesCtrEncryptDecrypt(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& data,
std::vector<uint8_t>* buffer) {
const blink::WebCryptoAesCtrParams* params = algorithm.aesCtrParams();
- const std::vector<uint8_t>& raw_key =
- SymKeyOpenSsl::Cast(key)->raw_key_data();
+ const std::vector<uint8_t>& raw_key = GetSymmetricKeyData(key);
if (params->counter().size() != 16)
return Status::ErrorIncorrectSizeAesCtrCounter();
@@ -261,8 +259,8 @@ class AesCtrImplementation : public AesAlgorithm {
} // namespace
-AlgorithmImplementation* CreatePlatformAesCtrImplementation() {
- return new AesCtrImplementation;
+scoped_ptr<AlgorithmImplementation> CreateAesCtrImplementation() {
+ return make_scoped_ptr(new AesCtrImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/aes_ctr_unittest.cc b/chromium/components/webcrypto/algorithms/aes_ctr_unittest.cc
new file mode 100644
index 00000000000..9bdbf38dcdb
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/aes_ctr_unittest.cc
@@ -0,0 +1,170 @@
+// 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 "base/stl_util.h"
+#include "base/values.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+// Creates an AES-CTR algorithm for encryption/decryption.
+blink::WebCryptoAlgorithm CreateAesCtrAlgorithm(
+ const std::vector<uint8_t>& counter,
+ uint8_t length_bits) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdAesCtr,
+ new blink::WebCryptoAesCtrParams(
+ length_bits, vector_as_array(&counter),
+ static_cast<unsigned int>(counter.size())));
+}
+
+class WebCryptoAesCtrTest : public WebCryptoTestBase {};
+
+TEST_F(WebCryptoAesCtrTest, EncryptDecryptKnownAnswer) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("aes_ctr.json", &tests));
+
+ 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));
+
+ std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key");
+ std::vector<uint8_t> test_counter = GetBytesFromHexString(test, "counter");
+ int counter_length_bits = 0;
+ ASSERT_TRUE(test->GetInteger("length", &counter_length_bits));
+
+ std::vector<uint8_t> test_plain_text =
+ GetBytesFromHexString(test, "plain_text");
+ std::vector<uint8_t> test_cipher_text =
+ GetBytesFromHexString(test, "cipher_text");
+
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw(
+ test_key, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCtr),
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
+
+ EXPECT_EQ(test_key.size() * 8, key.algorithm().aesParams()->lengthBits());
+
+ std::vector<uint8_t> output;
+
+ // Test encryption.
+ EXPECT_EQ(Status::Success(),
+ Encrypt(CreateAesCtrAlgorithm(test_counter, counter_length_bits),
+ key, CryptoData(test_plain_text), &output));
+ EXPECT_BYTES_EQ(test_cipher_text, output);
+
+ // Test decryption.
+ EXPECT_EQ(Status::Success(),
+ Decrypt(CreateAesCtrAlgorithm(test_counter, counter_length_bits),
+ key, CryptoData(test_cipher_text), &output));
+ EXPECT_BYTES_EQ(test_plain_text, output);
+ }
+}
+
+// The counter block must be exactly 16 bytes.
+TEST_F(WebCryptoAesCtrTest, InvalidCounterBlockLength) {
+ const unsigned int kBadCounterBlockLengthBytes[] = {0, 15, 17};
+
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw(
+ std::vector<uint8>(16), // 128-bit key of all zeros.
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCtr),
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
+
+ std::vector<uint8_t> input(32);
+ std::vector<uint8_t> output;
+
+ for (size_t i = 0; i < arraysize(kBadCounterBlockLengthBytes); ++i) {
+ std::vector<uint8_t> bad_counter(kBadCounterBlockLengthBytes[i]);
+
+ EXPECT_EQ(Status::ErrorIncorrectSizeAesCtrCounter(),
+ Encrypt(CreateAesCtrAlgorithm(bad_counter, 128), key,
+ CryptoData(input), &output));
+
+ EXPECT_EQ(Status::ErrorIncorrectSizeAesCtrCounter(),
+ Decrypt(CreateAesCtrAlgorithm(bad_counter, 128), key,
+ CryptoData(input), &output));
+ }
+}
+
+// The counter length cannot be less than 1 or greater than 128.
+TEST_F(WebCryptoAesCtrTest, InvalidCounterLength) {
+ const uint8_t kBadCounterLengthBits[] = {0, 129};
+
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw(
+ std::vector<uint8>(16), // 128-bit key of all zeros.
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCtr),
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
+
+ std::vector<uint8_t> counter(16);
+ std::vector<uint8_t> input(32);
+ std::vector<uint8_t> output;
+
+ for (size_t i = 0; i < arraysize(kBadCounterLengthBits); ++i) {
+ uint8_t bad_counter_length_bits = kBadCounterLengthBits[i];
+
+ EXPECT_EQ(Status::ErrorInvalidAesCtrCounterLength(),
+ Encrypt(CreateAesCtrAlgorithm(counter, bad_counter_length_bits),
+ key, CryptoData(input), &output));
+
+ EXPECT_EQ(Status::ErrorInvalidAesCtrCounterLength(),
+ Decrypt(CreateAesCtrAlgorithm(counter, bad_counter_length_bits),
+ key, CryptoData(input), &output));
+ }
+}
+
+// Tests wrap-around using a 4-bit counter.
+//
+// Wrap-around is allowed, however if the counter repeats itself an error should
+// be thrown.
+//
+// Using a 4-bit counter it is possible to encrypt 16 blocks. However the 17th
+// block would end up wrapping back to the starting value.
+TEST_F(WebCryptoAesCtrTest, OverflowAndRepeatCounter) {
+ const uint8_t kCounterLengthBits = 4;
+ const uint8_t kStartCounter[] = {0, 1, 15};
+
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw(
+ std::vector<uint8>(16), // 128-bit key of all zeros.
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCtr),
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
+
+ std::vector<uint8_t> buffer(272);
+
+ // 16 and 17 AES blocks worth of data respectively (AES blocks are 16 bytes
+ // long).
+ CryptoData input_16(vector_as_array(&buffer), 256);
+ CryptoData input_17(vector_as_array(&buffer), 272);
+
+ std::vector<uint8_t> output;
+
+ for (size_t i = 0; i < arraysize(kStartCounter); ++i) {
+ std::vector<uint8_t> counter(16);
+ counter[15] = kStartCounter[i];
+
+ // Baseline test: Encrypting 16 blocks should work (don't bother to check
+ // output, the known answer tests already do that).
+ EXPECT_EQ(Status::Success(),
+ Encrypt(CreateAesCtrAlgorithm(counter, kCounterLengthBits), key,
+ input_16, &output));
+
+ // Encrypting/Decrypting 17 however should fail.
+ EXPECT_EQ(Status::ErrorAesCtrInputTooLongCounterRepeated(),
+ Encrypt(CreateAesCtrAlgorithm(counter, kCounterLengthBits), key,
+ input_17, &output));
+ EXPECT_EQ(Status::ErrorAesCtrInputTooLongCounterRepeated(),
+ Decrypt(CreateAesCtrAlgorithm(counter, kCounterLengthBits), key,
+ input_17, &output));
+ }
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/aes_gcm_openssl.cc b/chromium/components/webcrypto/algorithms/aes_gcm.cc
index 564b54f88c7..3685bd93199 100644
--- a/chromium/components/webcrypto/openssl/aes_gcm_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/aes_gcm.cc
@@ -2,17 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <vector>
#include <openssl/evp.h>
+#include <vector>
#include "base/logging.h"
#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/aes.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/openssl/aes_algorithm_openssl.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -37,14 +36,21 @@ Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
const blink::WebCryptoKey& key,
const CryptoData& data,
std::vector<uint8_t>* buffer) {
- const std::vector<uint8_t>& raw_key =
- SymKeyOpenSsl::Cast(key)->raw_key_data();
+ const std::vector<uint8_t>& raw_key = GetSymmetricKeyData(key);
const blink::WebCryptoAesGcmParams* params = algorithm.aesGcmParams();
- unsigned int tag_length_bits;
- Status status = GetAesGcmTagLengthInBits(params, &tag_length_bits);
- if (status.IsError())
- return status;
+ // The WebCrypto spec defines the default value for the tag length, as well as
+ // the allowed values for tag length.
+ unsigned int tag_length_bits = 128;
+ if (params->hasTagLengthBits()) {
+ tag_length_bits = params->optionalTagLengthBits();
+ if (tag_length_bits != 32 && tag_length_bits != 64 &&
+ tag_length_bits != 96 && tag_length_bits != 104 &&
+ tag_length_bits != 112 && tag_length_bits != 120 &&
+ tag_length_bits != 128) {
+ return Status::ErrorInvalidAesGcmTagLength();
+ }
+ }
return AeadEncryptDecrypt(
mode, raw_key, data, tag_length_bits / 8, CryptoData(params->iv()),
@@ -73,8 +79,8 @@ class AesGcmImplementation : public AesAlgorithm {
} // namespace
-AlgorithmImplementation* CreatePlatformAesGcmImplementation() {
- return new AesGcmImplementation;
+scoped_ptr<AlgorithmImplementation> CreateAesGcmImplementation() {
+ return make_scoped_ptr(new AesGcmImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/aes_gcm_unittest.cc b/chromium/components/webcrypto/algorithms/aes_gcm_unittest.cc
new file mode 100644
index 00000000000..94ba9bea803
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/aes_gcm_unittest.cc
@@ -0,0 +1,222 @@
+// 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 "base/stl_util.h"
+#include "base/values.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+// Creates an AES-GCM algorithm.
+blink::WebCryptoAlgorithm CreateAesGcmAlgorithm(
+ const std::vector<uint8_t>& iv,
+ const std::vector<uint8_t>& additional_data,
+ unsigned int tag_length_bits) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdAesGcm,
+ new blink::WebCryptoAesGcmParams(
+ vector_as_array(&iv), static_cast<unsigned int>(iv.size()), true,
+ vector_as_array(&additional_data),
+ static_cast<unsigned int>(additional_data.size()), true,
+ tag_length_bits));
+}
+
+blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm(
+ unsigned short key_length_bits) {
+ return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesGcm,
+ key_length_bits);
+}
+
+Status AesGcmEncrypt(const blink::WebCryptoKey& key,
+ const std::vector<uint8_t>& iv,
+ const std::vector<uint8_t>& additional_data,
+ unsigned int tag_length_bits,
+ const std::vector<uint8_t>& plain_text,
+ std::vector<uint8_t>* cipher_text,
+ std::vector<uint8_t>* authentication_tag) {
+ blink::WebCryptoAlgorithm algorithm =
+ CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits);
+
+ std::vector<uint8_t> output;
+ Status status = Encrypt(algorithm, key, CryptoData(plain_text), &output);
+ if (status.IsError())
+ return status;
+
+ if ((tag_length_bits % 8) != 0) {
+ ADD_FAILURE() << "Encrypt should have failed.";
+ return Status::OperationError();
+ }
+
+ size_t tag_length_bytes = tag_length_bits / 8;
+
+ if (tag_length_bytes > output.size()) {
+ ADD_FAILURE() << "tag length is larger than output";
+ return Status::OperationError();
+ }
+
+ // The encryption result is cipher text with authentication tag appended.
+ cipher_text->assign(output.begin(),
+ output.begin() + (output.size() - tag_length_bytes));
+ authentication_tag->assign(output.begin() + cipher_text->size(),
+ output.end());
+
+ return Status::Success();
+}
+
+Status AesGcmDecrypt(const blink::WebCryptoKey& key,
+ const std::vector<uint8_t>& iv,
+ const std::vector<uint8_t>& additional_data,
+ unsigned int tag_length_bits,
+ const std::vector<uint8_t>& cipher_text,
+ const std::vector<uint8_t>& authentication_tag,
+ std::vector<uint8_t>* plain_text) {
+ blink::WebCryptoAlgorithm algorithm =
+ CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits);
+
+ // Join cipher text and authentication tag.
+ std::vector<uint8_t> cipher_text_with_tag;
+ cipher_text_with_tag.reserve(cipher_text.size() + authentication_tag.size());
+ cipher_text_with_tag.insert(cipher_text_with_tag.end(), cipher_text.begin(),
+ cipher_text.end());
+ cipher_text_with_tag.insert(cipher_text_with_tag.end(),
+ authentication_tag.begin(),
+ authentication_tag.end());
+
+ return Decrypt(algorithm, key, CryptoData(cipher_text_with_tag), plain_text);
+}
+
+class WebCryptoAesGcmTest : public WebCryptoTestBase {};
+
+TEST_F(WebCryptoAesGcmTest, GenerateKeyBadLength) {
+ const unsigned short kKeyLen[] = {0, 127, 257};
+ blink::WebCryptoKey key;
+ for (size_t i = 0; i < arraysize(kKeyLen); ++i) {
+ SCOPED_TRACE(i);
+ EXPECT_EQ(Status::ErrorGenerateAesKeyLength(),
+ GenerateSecretKey(CreateAesGcmKeyGenAlgorithm(kKeyLen[i]), true,
+ blink::WebCryptoKeyUsageDecrypt, &key));
+ }
+}
+
+TEST_F(WebCryptoAesGcmTest, GenerateKeyEmptyUsage) {
+ blink::WebCryptoKey key;
+ EXPECT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ GenerateSecretKey(CreateAesGcmKeyGenAlgorithm(256), true, 0, &key));
+}
+
+TEST_F(WebCryptoAesGcmTest, ImportExportJwk) {
+ const blink::WebCryptoAlgorithm algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm);
+
+ // AES-GCM 128
+ ImportExportJwkSymmetricKey(
+ 128, algorithm,
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
+ "A128GCM");
+
+ // AES-GCM 256
+ ImportExportJwkSymmetricKey(256, algorithm, blink::WebCryptoKeyUsageDecrypt,
+ "A256GCM");
+}
+
+// TODO(eroman):
+// * Test decryption when the tag length exceeds input size
+// * Test decryption with empty input
+// * Test decryption with tag length of 0.
+TEST_F(WebCryptoAesGcmTest, SampleSets) {
+ scoped_ptr<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) {
+ SCOPED_TRACE(test_index);
+ base::DictionaryValue* 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");
+ const std::vector<uint8_t> test_additional_data =
+ GetBytesFromHexString(test, "additional_data");
+ const std::vector<uint8_t> test_plain_text =
+ GetBytesFromHexString(test, "plain_text");
+ const std::vector<uint8_t> test_authentication_tag =
+ GetBytesFromHexString(test, "authentication_tag");
+ const unsigned int test_tag_size_bits =
+ static_cast<unsigned int>(test_authentication_tag.size()) * 8;
+ const std::vector<uint8_t> test_cipher_text =
+ GetBytesFromHexString(test, "cipher_text");
+
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw(
+ test_key, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm),
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
+
+ // Verify exported raw key is identical to the imported data
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+
+ EXPECT_BYTES_EQ(test_key, raw_key);
+
+ // Test encryption.
+ std::vector<uint8_t> cipher_text;
+ std::vector<uint8_t> authentication_tag;
+ EXPECT_EQ(
+ Status::Success(),
+ AesGcmEncrypt(key, test_iv, test_additional_data, test_tag_size_bits,
+ test_plain_text, &cipher_text, &authentication_tag));
+
+ EXPECT_BYTES_EQ(test_cipher_text, cipher_text);
+ EXPECT_BYTES_EQ(test_authentication_tag, authentication_tag);
+
+ // Test decryption.
+ std::vector<uint8_t> plain_text;
+ EXPECT_EQ(
+ Status::Success(),
+ AesGcmDecrypt(key, test_iv, test_additional_data, test_tag_size_bits,
+ test_cipher_text, test_authentication_tag, &plain_text));
+ EXPECT_BYTES_EQ(test_plain_text, plain_text);
+
+ // Decryption should fail if any of the inputs are tampered with.
+ EXPECT_EQ(Status::OperationError(),
+ AesGcmDecrypt(key, Corrupted(test_iv), test_additional_data,
+ test_tag_size_bits, test_cipher_text,
+ test_authentication_tag, &plain_text));
+ EXPECT_EQ(Status::OperationError(),
+ AesGcmDecrypt(key, test_iv, Corrupted(test_additional_data),
+ test_tag_size_bits, test_cipher_text,
+ test_authentication_tag, &plain_text));
+ EXPECT_EQ(Status::OperationError(),
+ AesGcmDecrypt(key, test_iv, test_additional_data,
+ test_tag_size_bits, Corrupted(test_cipher_text),
+ test_authentication_tag, &plain_text));
+ EXPECT_EQ(Status::OperationError(),
+ AesGcmDecrypt(key, test_iv, test_additional_data,
+ test_tag_size_bits, test_cipher_text,
+ Corrupted(test_authentication_tag), &plain_text));
+
+ // Try different incorrect tag lengths
+ uint8_t kAlternateTagLengths[] = {0, 8, 96, 120, 128, 160, 255};
+ for (size_t tag_i = 0; tag_i < arraysize(kAlternateTagLengths); ++tag_i) {
+ unsigned int wrong_tag_size_bits = kAlternateTagLengths[tag_i];
+ if (test_tag_size_bits == wrong_tag_size_bits)
+ continue;
+ EXPECT_NE(Status::Success(),
+ AesGcmDecrypt(key, test_iv, test_additional_data,
+ wrong_tag_size_bits, test_cipher_text,
+ test_authentication_tag, &plain_text));
+ }
+ }
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/aes_kw_openssl.cc b/chromium/components/webcrypto/algorithms/aes_kw.cc
index 31dacea3423..295d9114296 100644
--- a/chromium/components/webcrypto/openssl/aes_kw_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/aes_kw.cc
@@ -2,16 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <vector>
#include <openssl/evp.h>
+#include <vector>
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/aes.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/openssl/aes_algorithm_openssl.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
@@ -36,9 +36,8 @@ Status AesKwEncryptDecrypt(EncryptOrDecrypt mode,
const blink::WebCryptoKey& key,
const CryptoData& data,
std::vector<uint8_t>* buffer) {
- // These length checks are done so the returned error matches that of NSS
- // implementation. Other than giving a more specific error, these are not
- // required.
+ // These length checks are done in order to give a more specific error. These
+ // are not required for correctness.
if ((mode == ENCRYPT && data.byte_length() < 16) ||
(mode == DECRYPT && data.byte_length() < 24)) {
return Status::ErrorDataTooSmall();
@@ -46,8 +45,7 @@ Status AesKwEncryptDecrypt(EncryptOrDecrypt mode,
if (data.byte_length() % 8)
return Status::ErrorInvalidAesKwDataLength();
- const std::vector<uint8_t>& raw_key =
- SymKeyOpenSsl::Cast(key)->raw_key_data();
+ const std::vector<uint8_t>& raw_key = GetSymmetricKeyData(key);
return AeadEncryptDecrypt(mode, raw_key, data,
8, // tag_length_bytes
@@ -81,8 +79,8 @@ class AesKwImplementation : public AesAlgorithm {
} // namespace
-AlgorithmImplementation* CreatePlatformAesKwImplementation() {
- return new AesKwImplementation;
+scoped_ptr<AlgorithmImplementation> CreateAesKwImplementation() {
+ return make_scoped_ptr(new AesKwImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/aes_kw_unittest.cc b/chromium/components/webcrypto/algorithms/aes_kw_unittest.cc
new file mode 100644
index 00000000000..3002544a493
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/aes_kw_unittest.cc
@@ -0,0 +1,538 @@
+// 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 "base/stl_util.h"
+#include "base/values.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm(
+ unsigned short key_length_bits) {
+ return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesKw,
+ key_length_bits);
+}
+
+class WebCryptoAesKwTest : public WebCryptoTestBase {};
+
+TEST_F(WebCryptoAesKwTest, GenerateKeyBadLength) {
+ const unsigned short kKeyLen[] = {0, 127, 257};
+ blink::WebCryptoKey key;
+ for (size_t i = 0; i < arraysize(kKeyLen); ++i) {
+ SCOPED_TRACE(i);
+ EXPECT_EQ(Status::ErrorGenerateAesKeyLength(),
+ GenerateSecretKey(CreateAesKwKeyGenAlgorithm(kKeyLen[i]), true,
+ blink::WebCryptoKeyUsageWrapKey, &key));
+ }
+}
+
+TEST_F(WebCryptoAesKwTest, GenerateKeyEmptyUsage) {
+ blink::WebCryptoKey key;
+ EXPECT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ GenerateSecretKey(CreateAesKwKeyGenAlgorithm(256), true, 0, &key));
+}
+
+TEST_F(WebCryptoAesKwTest, ImportKeyEmptyUsage) {
+ blink::WebCryptoKey key;
+ EXPECT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(std::vector<uint8_t>(16)),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw), true,
+ 0, &key));
+}
+
+TEST_F(WebCryptoAesKwTest, ImportKeyJwkKeyOpsWrapUnwrap) {
+ blink::WebCryptoKey key;
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
+ base::ListValue* key_ops = new base::ListValue;
+ dict.Set("key_ops", key_ops); // Takes ownership.
+
+ key_ops->AppendString("wrapKey");
+
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw), false,
+ blink::WebCryptoKeyUsageWrapKey, &key));
+
+ EXPECT_EQ(blink::WebCryptoKeyUsageWrapKey, key.usages());
+
+ key_ops->AppendString("unwrapKey");
+
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw), false,
+ blink::WebCryptoKeyUsageUnwrapKey, &key));
+
+ EXPECT_EQ(blink::WebCryptoKeyUsageUnwrapKey, key.usages());
+}
+
+TEST_F(WebCryptoAesKwTest, ImportExportJwk) {
+ const blink::WebCryptoAlgorithm algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ // AES-KW 128
+ ImportExportJwkSymmetricKey(
+ 128, algorithm,
+ blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey,
+ "A128KW");
+
+ // AES-KW 256
+ ImportExportJwkSymmetricKey(
+ 256, algorithm,
+ blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey,
+ "A256KW");
+}
+
+TEST_F(WebCryptoAesKwTest, AesKwKeyImport) {
+ blink::WebCryptoKey key;
+ blink::WebCryptoAlgorithm algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ // Import a 128-bit Key Encryption Key (KEK)
+ std::string key_raw_hex_in = "025a8cf3f08b4f6c5f33bbc76a471939";
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm,
+ true, blink::WebCryptoKeyUsageWrapKey, &key));
+ std::vector<uint8_t> key_raw_out;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_raw_out));
+ EXPECT_BYTES_EQ_HEX(key_raw_hex_in, key_raw_out);
+
+ // Import a 192-bit KEK
+ key_raw_hex_in = "c0192c6466b2370decbb62b2cfef4384544ffeb4d2fbc103";
+ ASSERT_EQ(Status::ErrorAes192BitUnsupported(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm,
+ true, blink::WebCryptoKeyUsageWrapKey, &key));
+
+ // Import a 256-bit Key Encryption Key (KEK)
+ key_raw_hex_in =
+ "e11fe66380d90fa9ebefb74e0478e78f95664d0c67ca20ce4a0b5842863ac46f";
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm,
+ true, blink::WebCryptoKeyUsageWrapKey, &key));
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_raw_out));
+ EXPECT_BYTES_EQ_HEX(key_raw_hex_in, key_raw_out);
+
+ // Fail import of 0 length key
+ EXPECT_EQ(
+ Status::ErrorImportAesKeyLength(),
+ ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(HexStringToBytes("")),
+ algorithm, true, blink::WebCryptoKeyUsageWrapKey, &key));
+
+ // Fail import of 124-bit KEK
+ key_raw_hex_in = "3e4566a2bdaa10cb68134fa66c15ddb";
+ EXPECT_EQ(Status::ErrorImportAesKeyLength(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm,
+ true, blink::WebCryptoKeyUsageWrapKey, &key));
+
+ // Fail import of 200-bit KEK
+ key_raw_hex_in = "0a1d88608a5ad9fec64f1ada269ebab4baa2feeb8d95638c0e";
+ EXPECT_EQ(Status::ErrorImportAesKeyLength(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm,
+ true, blink::WebCryptoKeyUsageWrapKey, &key));
+
+ // Fail import of 260-bit KEK
+ key_raw_hex_in =
+ "72d4e475ff34215416c9ad9c8281247a4d730c5f275ac23f376e73e3bce8d7d5a";
+ EXPECT_EQ(Status::ErrorImportAesKeyLength(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(HexStringToBytes(key_raw_hex_in)), algorithm,
+ true, blink::WebCryptoKeyUsageWrapKey, &key));
+}
+
+TEST_F(WebCryptoAesKwTest, UnwrapFailures) {
+ // This test exercises the code path common to all unwrap operations.
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
+ base::DictionaryValue* 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");
+
+ blink::WebCryptoKey unwrapped_key;
+
+ // Using a wrapping algorithm that does not match the wrapping key algorithm
+ // should fail.
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+ test_kek, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
+ blink::WebCryptoKeyUsageUnwrapKey);
+ EXPECT_EQ(Status::ErrorUnexpected(),
+ UnwrapKey(blink::WebCryptoKeyFormatRaw, CryptoData(test_ciphertext),
+ wrapping_key,
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true,
+ blink::WebCryptoKeyUsageEncrypt, &unwrapped_key));
+}
+
+TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyWrapUnwrapKnownAnswer) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
+
+ 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));
+ 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 =
+ GetBytesFromHexString(test, "ciphertext");
+ const blink::WebCryptoAlgorithm wrapping_algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ // Import the wrapping key.
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+ test_kek, wrapping_algorithm,
+ blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey);
+
+ // Import the key to be wrapped.
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw(
+ test_key,
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha1),
+ blink::WebCryptoKeyUsageSign);
+
+ // Wrap the key and verify the ciphertext result against the known answer.
+ std::vector<uint8_t> wrapped_key;
+ ASSERT_EQ(Status::Success(),
+ WrapKey(blink::WebCryptoKeyFormatRaw, key, wrapping_key,
+ wrapping_algorithm, &wrapped_key));
+ EXPECT_BYTES_EQ(test_ciphertext, wrapped_key);
+
+ // Unwrap the known ciphertext to get a new test_key.
+ blink::WebCryptoKey unwrapped_key;
+ ASSERT_EQ(
+ Status::Success(),
+ UnwrapKey(
+ blink::WebCryptoKeyFormatRaw, CryptoData(test_ciphertext),
+ wrapping_key, wrapping_algorithm,
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageSign, &unwrapped_key));
+ EXPECT_FALSE(key.isNull());
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id());
+ EXPECT_EQ(true, key.extractable());
+ EXPECT_EQ(blink::WebCryptoKeyUsageSign, key.usages());
+
+ // Export the new key and compare its raw bytes with the original known key.
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key));
+ EXPECT_BYTES_EQ(test_key, raw_key);
+ }
+}
+
+// Unwrap a HMAC key using AES-KW, and then try doing a sign/verify with the
+// unwrapped key
+TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyUnwrapSignVerifyHmac) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
+
+ base::DictionaryValue* 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");
+ const blink::WebCryptoAlgorithm wrapping_algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ // Import the wrapping key.
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+ test_kek, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey);
+
+ // Unwrap the known ciphertext.
+ blink::WebCryptoKey key;
+ ASSERT_EQ(
+ Status::Success(),
+ UnwrapKey(
+ blink::WebCryptoKeyFormatRaw, CryptoData(test_ciphertext),
+ wrapping_key, wrapping_algorithm,
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha1),
+ false, blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
+ &key));
+
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id());
+ EXPECT_FALSE(key.extractable());
+ EXPECT_EQ(blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
+ key.usages());
+
+ // Sign an empty message and ensure it is verified.
+ std::vector<uint8_t> test_message;
+ std::vector<uint8_t> signature;
+
+ ASSERT_EQ(Status::Success(),
+ Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), key,
+ CryptoData(test_message), &signature));
+
+ EXPECT_GT(signature.size(), 0u);
+
+ bool verify_result;
+ ASSERT_EQ(
+ Status::Success(),
+ Verify(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), key,
+ CryptoData(signature), CryptoData(test_message), &verify_result));
+}
+
+TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyWrapUnwrapErrors) {
+ scoped_ptr<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));
+ 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 =
+ GetBytesFromHexString(test, "ciphertext");
+ const blink::WebCryptoAlgorithm wrapping_algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+ const blink::WebCryptoAlgorithm key_algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
+ // Import the wrapping key.
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+ test_kek, wrapping_algorithm,
+ blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey);
+ // Import the key to be wrapped.
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw(
+ test_key, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
+ blink::WebCryptoKeyUsageEncrypt);
+
+ // Unwrap with wrapped data too small must fail.
+ const std::vector<uint8_t> small_data(test_ciphertext.begin(),
+ test_ciphertext.begin() + 23);
+ blink::WebCryptoKey unwrapped_key;
+ EXPECT_EQ(Status::ErrorDataTooSmall(),
+ UnwrapKey(blink::WebCryptoKeyFormatRaw, CryptoData(small_data),
+ wrapping_key, wrapping_algorithm, key_algorithm, true,
+ blink::WebCryptoKeyUsageEncrypt, &unwrapped_key));
+
+ // Unwrap with wrapped data size not a multiple of 8 bytes must fail.
+ const std::vector<uint8_t> unaligned_data(test_ciphertext.begin(),
+ test_ciphertext.end() - 2);
+ EXPECT_EQ(Status::ErrorInvalidAesKwDataLength(),
+ UnwrapKey(blink::WebCryptoKeyFormatRaw, CryptoData(unaligned_data),
+ wrapping_key, wrapping_algorithm, key_algorithm, true,
+ blink::WebCryptoKeyUsageEncrypt, &unwrapped_key));
+}
+
+TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyUnwrapCorruptData) {
+ scoped_ptr<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));
+ 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 =
+ GetBytesFromHexString(test, "ciphertext");
+ const blink::WebCryptoAlgorithm wrapping_algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ // Import the wrapping key.
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+ test_kek, wrapping_algorithm,
+ blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey);
+
+ // Unwrap of a corrupted version of the known ciphertext should fail, due to
+ // AES-KW's built-in integrity check.
+ blink::WebCryptoKey unwrapped_key;
+ EXPECT_EQ(Status::OperationError(),
+ UnwrapKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(Corrupted(test_ciphertext)), wrapping_key,
+ wrapping_algorithm,
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true,
+ blink::WebCryptoKeyUsageEncrypt, &unwrapped_key));
+}
+
+TEST_F(WebCryptoAesKwTest, AesKwJwkSymkeyUnwrapKnownData) {
+ // The following data lists a known HMAC SHA-256 key, then a JWK
+ // representation of this key which was encrypted ("wrapped") using AES-KW and
+ // the following wrapping key.
+ // For reference, the intermediate clear JWK is
+ // {"alg":"HS256","ext":true,"k":<b64urlKey>,"key_ops":["verify"],"kty":"oct"}
+ // (Not shown is space padding to ensure the cleartext meets the size
+ // requirements of the AES-KW algorithm.)
+ const std::vector<uint8_t> key_data = HexStringToBytes(
+ "000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F");
+ const std::vector<uint8_t> wrapped_key_data = HexStringToBytes(
+ "14E6380B35FDC5B72E1994764B6CB7BFDD64E7832894356AAEE6C3768FC3D0F115E6B0"
+ "6729756225F999AA99FDF81FD6A359F1576D3D23DE6CB69C3937054EB497AC1E8C38D5"
+ "5E01B9783A20C8D930020932CF25926103002213D0FC37279888154FEBCEDF31832158"
+ "97938C5CFE5B10B4254D0C399F39D0");
+ const std::vector<uint8_t> wrapping_key_data =
+ HexStringToBytes("000102030405060708090A0B0C0D0E0F");
+ const blink::WebCryptoAlgorithm wrapping_algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ // Import the wrapping key.
+ blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+ wrapping_key_data, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey);
+
+ // Unwrap the known wrapped key data to produce a new key
+ blink::WebCryptoKey unwrapped_key;
+ ASSERT_EQ(
+ Status::Success(),
+ UnwrapKey(
+ blink::WebCryptoKeyFormatJwk, CryptoData(wrapped_key_data),
+ wrapping_key, wrapping_algorithm,
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha256),
+ true, blink::WebCryptoKeyUsageVerify, &unwrapped_key));
+
+ // Validate the new key's attributes.
+ EXPECT_FALSE(unwrapped_key.isNull());
+ EXPECT_TRUE(unwrapped_key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, unwrapped_key.type());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, unwrapped_key.algorithm().id());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256,
+ unwrapped_key.algorithm().hmacParams()->hash().id());
+ EXPECT_EQ(256u, unwrapped_key.algorithm().hmacParams()->lengthBits());
+ EXPECT_EQ(true, unwrapped_key.extractable());
+ EXPECT_EQ(blink::WebCryptoKeyUsageVerify, unwrapped_key.usages());
+
+ // Export the new key's raw data and compare to the known original.
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key));
+ EXPECT_BYTES_EQ(key_data, raw_key);
+}
+
+// Try importing an AES-KW key with unsupported key usages using raw
+// format. AES-KW keys support the following usages:
+// 'wrapKey', 'unwrapKey'
+TEST_F(WebCryptoAesKwTest, ImportKeyBadUsage_Raw) {
+ const blink::WebCryptoAlgorithm algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ blink::WebCryptoKeyUsageMask bad_usages[] = {
+ blink::WebCryptoKeyUsageEncrypt,
+ blink::WebCryptoKeyUsageDecrypt,
+ blink::WebCryptoKeyUsageSign,
+ blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageUnwrapKey,
+ blink::WebCryptoKeyUsageDeriveBits,
+ blink::WebCryptoKeyUsageUnwrapKey | blink::WebCryptoKeyUsageVerify,
+ };
+
+ std::vector<uint8_t> key_bytes(16);
+
+ for (size_t i = 0; i < arraysize(bad_usages); ++i) {
+ SCOPED_TRACE(i);
+
+ blink::WebCryptoKey key;
+ ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
+ ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(key_bytes),
+ algorithm, true, bad_usages[i], &key));
+ }
+}
+
+// Try unwrapping an HMAC key with unsupported usages using JWK format and
+// AES-KW. HMAC keys support the following usages:
+// 'sign', 'verify'
+TEST_F(WebCryptoAesKwTest, UnwrapHmacKeyBadUsage_JWK) {
+ const blink::WebCryptoAlgorithm unwrap_algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ blink::WebCryptoKeyUsageMask bad_usages[] = {
+ blink::WebCryptoKeyUsageEncrypt,
+ blink::WebCryptoKeyUsageDecrypt,
+ blink::WebCryptoKeyUsageWrapKey,
+ blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageWrapKey,
+ blink::WebCryptoKeyUsageVerify | blink::WebCryptoKeyUsageDeriveKey,
+ };
+
+ // Import the wrapping key.
+ blink::WebCryptoKey wrapping_key;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(std::vector<uint8_t>(16)), unwrap_algorithm,
+ true, blink::WebCryptoKeyUsageUnwrapKey, &wrapping_key));
+
+ // The JWK plain text is:
+ // {"kty":"oct","alg":"HS256","k":"GADWrMRHwQfoNaXU5fZvTg"}
+ const char* kWrappedJwk =
+ "C2B7F19A32EE31372CD40C9C969B8CD67553E5AEA7FD1144874584E46ABCD79FDC308848"
+ "B2DD8BD36A2D61062B9C5B8B499B8D6EF8EB320D87A614952B4EE771";
+
+ for (size_t i = 0; i < arraysize(bad_usages); ++i) {
+ SCOPED_TRACE(i);
+
+ blink::WebCryptoKey key;
+
+ ASSERT_EQ(
+ Status::ErrorCreateKeyBadUsages(),
+ UnwrapKey(blink::WebCryptoKeyFormatJwk,
+ CryptoData(HexStringToBytes(kWrappedJwk)), wrapping_key,
+ unwrap_algorithm, CreateHmacImportAlgorithmNoLength(
+ blink::WebCryptoAlgorithmIdSha256),
+ true, bad_usages[i], &key));
+ }
+}
+
+// Try unwrapping an RSA-SSA public key with unsupported usages using JWK format
+// and AES-KW. RSA-SSA public keys support the following usages:
+// 'verify'
+TEST_F(WebCryptoAesKwTest, UnwrapRsaSsaPublicKeyBadUsage_JWK) {
+ const blink::WebCryptoAlgorithm unwrap_algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+ blink::WebCryptoKeyUsageMask bad_usages[] = {
+ blink::WebCryptoKeyUsageEncrypt,
+ blink::WebCryptoKeyUsageSign,
+ blink::WebCryptoKeyUsageDecrypt,
+ blink::WebCryptoKeyUsageWrapKey,
+ blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageWrapKey,
+ };
+
+ // Import the wrapping key.
+ blink::WebCryptoKey wrapping_key;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(std::vector<uint8_t>(16)), unwrap_algorithm,
+ true, blink::WebCryptoKeyUsageUnwrapKey, &wrapping_key));
+
+ // The JWK plaintext is:
+ // { "kty": "RSA","alg": "RS256","n": "...","e": "AQAB"}
+
+ const char* kWrappedJwk =
+ "CE8DAEF99E977EE58958B8C4494755C846E883B2ECA575C5366622839AF71AB30875F152"
+ "E8E33E15A7817A3A2874EB53EFE05C774D98BC936BA9BA29BEB8BB3F3C3CE2323CB3359D"
+ "E3F426605CF95CCF0E01E870ABD7E35F62E030B5FB6E520A5885514D1D850FB64B57806D"
+ "1ADA57C6E27DF345D8292D80F6B074F1BE51C4CF3D76ECC8886218551308681B44FAC60B"
+ "8CF6EA439BC63239103D0AE81ADB96F908680586C6169284E32EB7DD09D31103EBDAC0C2"
+ "40C72DCF0AEA454113CC47457B13305B25507CBEAB9BDC8D8E0F867F9167F9DCEF0D9F9B"
+ "30F2EE83CEDFD51136852C8A5939B768";
+
+ for (size_t i = 0; i < arraysize(bad_usages); ++i) {
+ SCOPED_TRACE(i);
+
+ blink::WebCryptoKey key;
+
+ ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
+ UnwrapKey(blink::WebCryptoKeyFormatJwk,
+ CryptoData(HexStringToBytes(kWrappedJwk)), wrapping_key,
+ unwrap_algorithm,
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, bad_usages[i], &key));
+ }
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/util_openssl.cc b/chromium/components/webcrypto/algorithms/asymmetric_key_util.cc
index b6ada7007e3..9abd47ce28c 100644
--- a/chromium/components/webcrypto/openssl/util_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/asymmetric_key_util.cc
@@ -1,20 +1,16 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// 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/webcrypto/openssl/util_openssl.h"
+#include "components/webcrypto/algorithms/asymmetric_key_util.h"
-#include <openssl/evp.h>
#include <openssl/pkcs12.h>
-#include <openssl/rand.h>
-#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/platform_crypto.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
namespace webcrypto {
@@ -61,110 +57,6 @@ Status ExportPKeyPkcs8(EVP_PKEY* key, std::vector<uint8_t>* buffer) {
} // namespace
-void PlatformInit() {
- crypto::EnsureOpenSSLInit();
-}
-
-const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id) {
- switch (id) {
- case blink::WebCryptoAlgorithmIdSha1:
- return EVP_sha1();
- case blink::WebCryptoAlgorithmIdSha256:
- return EVP_sha256();
- case blink::WebCryptoAlgorithmIdSha384:
- return EVP_sha384();
- case blink::WebCryptoAlgorithmIdSha512:
- return EVP_sha512();
- default:
- return NULL;
- }
-}
-
-Status AeadEncryptDecrypt(EncryptOrDecrypt mode,
- const std::vector<uint8_t>& raw_key,
- const CryptoData& data,
- unsigned int tag_length_bytes,
- const CryptoData& iv,
- const CryptoData& additional_data,
- const EVP_AEAD* aead_alg,
- std::vector<uint8_t>* buffer) {
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- EVP_AEAD_CTX ctx;
-
- if (!aead_alg)
- return Status::ErrorUnexpected();
-
- if (!EVP_AEAD_CTX_init(&ctx, aead_alg, vector_as_array(&raw_key),
- raw_key.size(), tag_length_bytes, NULL)) {
- return Status::OperationError();
- }
-
- crypto::ScopedOpenSSL<EVP_AEAD_CTX, EVP_AEAD_CTX_cleanup> ctx_cleanup(&ctx);
-
- size_t len;
- int ok;
-
- if (mode == DECRYPT) {
- if (data.byte_length() < tag_length_bytes)
- return Status::ErrorDataTooSmall();
-
- buffer->resize(data.byte_length() - tag_length_bytes);
-
- ok = EVP_AEAD_CTX_open(&ctx, vector_as_array(buffer), &len, buffer->size(),
- iv.bytes(), iv.byte_length(), data.bytes(),
- data.byte_length(), additional_data.bytes(),
- additional_data.byte_length());
- } else {
- // No need to check for unsigned integer overflow here (seal fails if
- // the output buffer is too small).
- buffer->resize(data.byte_length() + EVP_AEAD_max_overhead(aead_alg));
-
- ok = EVP_AEAD_CTX_seal(&ctx, vector_as_array(buffer), &len, buffer->size(),
- iv.bytes(), iv.byte_length(), data.bytes(),
- data.byte_length(), additional_data.bytes(),
- additional_data.byte_length());
- }
-
- if (!ok)
- return Status::OperationError();
- buffer->resize(len);
- return Status::Success();
-}
-
-Status GenerateWebCryptoSecretKey(const blink::WebCryptoKeyAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- unsigned int keylen_bits,
- GenerateKeyResult* result) {
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
-
- unsigned int keylen_bytes = NumBitsToBytes(keylen_bits);
- std::vector<unsigned char> random_bytes(keylen_bytes, 0);
-
- if (keylen_bytes > 0) {
- if (!(RAND_bytes(&random_bytes[0], keylen_bytes)))
- return Status::OperationError();
- TruncateToBitLength(keylen_bits, &random_bytes);
- }
-
- result->AssignSecretKey(blink::WebCryptoKey::create(
- new SymKeyOpenSsl(CryptoData(random_bytes)),
- blink::WebCryptoKeyTypeSecret, extractable, algorithm, usages));
-
- return Status::Success();
-}
-
-Status CreateWebCryptoSecretKey(const CryptoData& key_data,
- const blink::WebCryptoKeyAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) {
- *key = blink::WebCryptoKey::create(new SymKeyOpenSsl(key_data),
- blink::WebCryptoKeyTypeSecret, extractable,
- algorithm, usages);
- return Status::Success();
-}
-
Status CreateWebCryptoPublicKey(crypto::ScopedEVP_PKEY public_key,
const blink::WebCryptoKeyAlgorithm& algorithm,
bool extractable,
@@ -178,7 +70,7 @@ Status CreateWebCryptoPublicKey(crypto::ScopedEVP_PKEY public_key,
return status;
*key = blink::WebCryptoKey::create(
- new AsymKeyOpenSsl(public_key.Pass(), CryptoData(spki_data)),
+ CreateAsymmetricKeyHandle(public_key.Pass(), spki_data),
blink::WebCryptoKeyTypePublic, extractable, algorithm, usages);
return Status::Success();
}
@@ -196,11 +88,25 @@ Status CreateWebCryptoPrivateKey(crypto::ScopedEVP_PKEY private_key,
return status;
*key = blink::WebCryptoKey::create(
- new AsymKeyOpenSsl(private_key.Pass(), CryptoData(pkcs8_data)),
+ CreateAsymmetricKeyHandle(private_key.Pass(), pkcs8_data),
blink::WebCryptoKeyTypePrivate, extractable, algorithm, usages);
return Status::Success();
}
+Status CheckPrivateKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages) {
+ return CheckKeyCreationUsages(all_possible_usages, actual_usages,
+ EmptyUsagePolicy::REJECT_EMPTY);
+}
+
+Status CheckPublicKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages) {
+ return CheckKeyCreationUsages(all_possible_usages, actual_usages,
+ EmptyUsagePolicy::ALLOW_EMPTY);
+}
+
Status ImportUnverifiedPkeyFromSpki(const CryptoData& key_data,
int expected_pkey_id,
crypto::ScopedEVP_PKEY* pkey) {
@@ -238,14 +144,51 @@ Status ImportUnverifiedPkeyFromPkcs8(const CryptoData& key_data,
return Status::Success();
}
-BIGNUM* CreateBIGNUM(const std::string& n) {
- return BN_bin2bn(reinterpret_cast<const uint8_t*>(n.data()), n.size(), NULL);
+Status VerifyUsagesBeforeImportAsymmetricKey(
+ blink::WebCryptoKeyFormat format,
+ blink::WebCryptoKeyUsageMask all_public_key_usages,
+ blink::WebCryptoKeyUsageMask all_private_key_usages,
+ blink::WebCryptoKeyUsageMask usages) {
+ switch (format) {
+ case blink::WebCryptoKeyFormatSpki:
+ return CheckPublicKeyCreationUsages(all_public_key_usages, usages);
+ case blink::WebCryptoKeyFormatPkcs8:
+ return CheckPrivateKeyCreationUsages(all_private_key_usages, usages);
+ case blink::WebCryptoKeyFormatJwk: {
+ // The JWK could represent either a public key or private key. The usages
+ // must make sense for one of the two. The usages will be checked again by
+ // ImportKeyJwk() once the key type has been determined.
+ if (CheckPublicKeyCreationUsages(all_public_key_usages, usages)
+ .IsError() &&
+ CheckPrivateKeyCreationUsages(all_private_key_usages, usages)
+ .IsError()) {
+ return Status::ErrorCreateKeyBadUsages();
+ }
+ return Status::Success();
+ }
+ default:
+ return Status::ErrorUnsupportedImportKeyFormat();
+ }
}
-std::vector<uint8_t> BIGNUMToVector(const BIGNUM* n) {
- std::vector<uint8_t> v(BN_num_bytes(n));
- BN_bn2bin(n, vector_as_array(&v));
- return v;
+Status GetUsagesForGenerateAsymmetricKey(
+ blink::WebCryptoKeyUsageMask combined_usages,
+ blink::WebCryptoKeyUsageMask all_public_usages,
+ blink::WebCryptoKeyUsageMask all_private_usages,
+ blink::WebCryptoKeyUsageMask* public_usages,
+ blink::WebCryptoKeyUsageMask* private_usages) {
+ // Ensure that the combined usages is a subset of the total possible usages.
+ Status status =
+ CheckKeyCreationUsages(all_public_usages | all_private_usages,
+ combined_usages, EmptyUsagePolicy::ALLOW_EMPTY);
+ if (status.IsError())
+ return status;
+
+ *public_usages = combined_usages & all_public_usages;
+ *private_usages = combined_usages & all_private_usages;
+
+ // Ensure that the private key has non-empty usages.
+ return CheckPrivateKeyCreationUsages(all_private_usages, *private_usages);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/asymmetric_key_util.h b/chromium/components/webcrypto/algorithms/asymmetric_key_util.h
new file mode 100644
index 00000000000..51ed79a8d13
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/asymmetric_key_util.h
@@ -0,0 +1,83 @@
+// 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_WEBCRYPTO_ALGORITHMS_ASYMMETRIC_KEY_UTIL_
+#define COMPONENTS_WEBCRYPTO_ALGORITHMS_ASYMMETRIC_KEY_UTIL_
+
+#include "crypto/scoped_openssl_types.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
+#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+
+// This file contains functions shared by multiple asymmetric key algorithms.
+
+namespace webcrypto {
+
+class CryptoData;
+class Status;
+
+// Creates a WebCrypto public key given an EVP_PKEY. This step includes
+// exporting the key to SPKI format, for use by serialization later.
+Status CreateWebCryptoPublicKey(crypto::ScopedEVP_PKEY public_key,
+ const blink::WebCryptoKeyAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoKey* key);
+
+// Creates a WebCrypto private key given an EVP_PKEY. This step includes
+// exporting the key to PKCS8 format, for use by serialization later.
+Status CreateWebCryptoPrivateKey(crypto::ScopedEVP_PKEY private_key,
+ const blink::WebCryptoKeyAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoKey* key);
+
+// Checks that a private key can be created using |actual_usages|, where
+// |all_possible_usages| is the full set of allowed private key usages. Note
+// that private keys are not allowed to have empty usages.
+Status CheckPrivateKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages);
+
+// Checks that a public key can be created using |actual_usages|, where
+// |all_possible_usages| is the full set of allowed public key usages
+Status CheckPublicKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages);
+
+// Imports SPKI bytes to an EVP_PKEY for a public key. The resulting asymmetric
+// key may be invalid, and should be verified using something like
+// RSA_check_key(). The only validation performed by this function is to ensure
+// the key type matched |expected_pkey_id|.
+Status ImportUnverifiedPkeyFromSpki(const CryptoData& key_data,
+ int expected_pkey_id,
+ crypto::ScopedEVP_PKEY* pkey);
+
+// Imports PKCS8 bytes to an EVP_PKEY for a private key. The resulting
+// asymmetric key may be invalid, and should be verified using something like
+// RSA_check_key(). The only validation performed by this function is to ensure
+// the key type matched |expected_pkey_id|.
+Status ImportUnverifiedPkeyFromPkcs8(const CryptoData& key_data,
+ int expected_pkey_id,
+ crypto::ScopedEVP_PKEY* pkey);
+
+// Verifies that |usages| is valid when importing a key of the given format.
+Status VerifyUsagesBeforeImportAsymmetricKey(
+ blink::WebCryptoKeyFormat format,
+ blink::WebCryptoKeyUsageMask all_public_key_usages,
+ blink::WebCryptoKeyUsageMask all_private_key_usages,
+ blink::WebCryptoKeyUsageMask usages);
+
+// Splits the combined usages given to GenerateKey() into the respective usages
+// for the public key and private key. Returns an error if the usages are
+// invalid.
+Status GetUsagesForGenerateAsymmetricKey(
+ blink::WebCryptoKeyUsageMask combined_usages,
+ blink::WebCryptoKeyUsageMask all_public_usages,
+ blink::WebCryptoKeyUsageMask all_private_usages,
+ blink::WebCryptoKeyUsageMask* public_usages,
+ blink::WebCryptoKeyUsageMask* private_usages);
+
+} // namespace webcrypto
+
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_ASYMMETRIC_KEY_UTIL_
diff --git a/chromium/components/webcrypto/openssl/ec_algorithm_openssl.cc b/chromium/components/webcrypto/algorithms/ec.cc
index 85f95eabe3d..20baa57f6d2 100644
--- a/chromium/components/webcrypto/openssl/ec_algorithm_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/ec.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/webcrypto/openssl/ec_algorithm_openssl.h"
+#include "components/webcrypto/algorithms/ec.h"
#include <openssl/ec.h>
#include <openssl/ec_key.h>
@@ -11,13 +11,13 @@
#include "base/logging.h"
#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/asymmetric_key_util.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -209,6 +209,15 @@ Status GetPublicKey(EC_KEY* ec,
return Status::Success();
}
+// Synthesizes an import algorithm given a key algorithm, so that
+// deserialization can re-use the ImportKey*() methods.
+blink::WebCryptoAlgorithm SynthesizeImportAlgorithmForClone(
+ const blink::WebCryptoKeyAlgorithm& algorithm) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ algorithm.id(), new blink::WebCryptoEcKeyImportParams(
+ algorithm.ecParams()->namedCurve()));
+}
+
} // namespace
Status EcAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
@@ -379,9 +388,12 @@ Status EcAlgorithm::ImportKeyJwk(const CryptoData& key_data,
bool is_private_key = jwk.HasMember("d");
// Now that the key type is known, verify the usages.
- status = CheckKeyCreationUsages(
- is_private_key ? all_private_key_usages_ : all_public_key_usages_, usages,
- !is_private_key);
+ if (is_private_key) {
+ status = CheckPrivateKeyCreationUsages(all_private_key_usages_, usages);
+ } else {
+ status = CheckPublicKeyCreationUsages(all_public_key_usages_, usages);
+ }
+
if (status.IsError())
return status;
@@ -448,7 +460,10 @@ Status EcAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const {
if (key.type() != blink::WebCryptoKeyTypePrivate)
return Status::ErrorUnexpectedKeyType();
- *buffer = AsymKeyOpenSsl::Cast(key)->serialized_key_data();
+ // This relies on the fact that PKCS8 formatted data was already
+ // associated with the key during its creation (used by
+ // structured clone).
+ *buffer = GetSerializedKeyData(key);
return Status::Success();
}
@@ -456,7 +471,10 @@ Status EcAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const {
if (key.type() != blink::WebCryptoKeyTypePublic)
return Status::ErrorUnexpectedKeyType();
- *buffer = AsymKeyOpenSsl::Cast(key)->serialized_key_data();
+ // This relies on the fact that SPKI formatted data was already
+ // associated with the key during its creation (used by
+ // structured clone).
+ *buffer = GetSerializedKeyData(key);
return Status::Success();
}
@@ -466,7 +484,7 @@ Status EcAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- EVP_PKEY* pkey = AsymKeyOpenSsl::Cast(key)->key();
+ EVP_PKEY* pkey = GetEVP_PKEY(key);
crypto::ScopedEC_KEY ec(EVP_PKEY_get1_EC_KEY(pkey));
if (!ec.get())
@@ -511,13 +529,6 @@ Status EcAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key,
return Status::Success();
}
-Status EcAlgorithm::SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const {
- key_data->assign(AsymKeyOpenSsl::Cast(key)->serialized_key_data());
- return Status::Success();
-}
-
// TODO(eroman): Defer import to the crypto thread. http://crbug.com/430763
Status EcAlgorithm::DeserializeKeyForClone(
const blink::WebCryptoKeyAlgorithm& algorithm,
@@ -526,11 +537,12 @@ Status EcAlgorithm::DeserializeKeyForClone(
blink::WebCryptoKeyUsageMask usages,
const CryptoData& key_data,
blink::WebCryptoKey* key) const {
- blink::WebCryptoAlgorithm import_algorithm = CreateEcImportAlgorithm(
- algorithm.id(), algorithm.ecParams()->namedCurve());
+ blink::WebCryptoAlgorithm import_algorithm =
+ SynthesizeImportAlgorithmForClone(algorithm);
Status status;
+ // The serialized data will be either SPKI or PKCS8 formatted.
switch (type) {
case blink::WebCryptoKeyTypePublic:
status =
diff --git a/chromium/components/webcrypto/openssl/ec_algorithm_openssl.h b/chromium/components/webcrypto/algorithms/ec.h
index 9771f3d6142..bebf87bf089 100644
--- a/chromium/components/webcrypto/openssl/ec_algorithm_openssl.h
+++ b/chromium/components/webcrypto/algorithms/ec.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_WEBCRYPTO_OPENSSL_EC_ALGORITHM_OPENSSL_H_
-#define COMPONENTS_WEBCRYPTO_OPENSSL_EC_ALGORITHM_OPENSSL_H_
+#ifndef COMPONENTS_WEBCRYPTO_ALGORITHMS_EC_H_
+#define COMPONENTS_WEBCRYPTO_ALGORITHMS_EC_H_
#include "components/webcrypto/algorithm_implementation.h"
@@ -61,10 +61,6 @@ class EcAlgorithm : public AlgorithmImplementation {
Status ExportKeyJwk(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const override;
- Status SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const override;
-
Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
blink::WebCryptoKeyType type,
bool extractable,
@@ -79,4 +75,4 @@ class EcAlgorithm : public AlgorithmImplementation {
} // namespace webcrypto
-#endif // COMPONENTS_WEBCRYPTO_OPENSSL_EC_ALGORITHM_OPENSSL_H_
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_EC_H_
diff --git a/chromium/components/webcrypto/openssl/ecdh_openssl.cc b/chromium/components/webcrypto/algorithms/ecdh.cc
index c0b264d2fc2..9da36e97411 100644
--- a/chromium/components/webcrypto/openssl/ecdh_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/ecdh.cc
@@ -9,13 +9,12 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
+#include "components/webcrypto/algorithms/ec.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
-#include "components/webcrypto/openssl/ec_algorithm_openssl.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "crypto/secure_util.h"
@@ -79,13 +78,13 @@ class EcdhImplementation : public EcAlgorithm {
}
crypto::ScopedEC_KEY public_key_ec(
- EVP_PKEY_get1_EC_KEY(AsymKeyOpenSsl::Cast(public_key)->key()));
+ EVP_PKEY_get1_EC_KEY(GetEVP_PKEY(public_key)));
const EC_POINT* public_key_point =
EC_KEY_get0_public_key(public_key_ec.get());
crypto::ScopedEC_KEY private_key_ec(
- EVP_PKEY_get1_EC_KEY(AsymKeyOpenSsl::Cast(base_key)->key()));
+ EVP_PKEY_get1_EC_KEY(GetEVP_PKEY(base_key)));
// The size of the shared secret is the field size in bytes (rounded up).
// Note that, if rounding was required, the most significant bits of the
@@ -126,8 +125,8 @@ class EcdhImplementation : public EcAlgorithm {
} // namespace
-AlgorithmImplementation* CreatePlatformEcdhImplementation() {
- return new EcdhImplementation;
+scoped_ptr<AlgorithmImplementation> CreateEcdhImplementation() {
+ return make_scoped_ptr(new EcdhImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/ecdh_unittest.cc b/chromium/components/webcrypto/algorithms/ecdh_unittest.cc
new file mode 100644
index 00000000000..961c6d5fa0c
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/ecdh_unittest.cc
@@ -0,0 +1,331 @@
+// 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 "base/stl_util.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/ec.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/jwk.h"
+#include "components/webcrypto/status.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+// TODO(eroman): Test passing an RSA public key instead of ECDH key.
+// TODO(eroman): Test passing an ECDSA public key
+
+blink::WebCryptoAlgorithm CreateEcdhImportAlgorithm(
+ blink::WebCryptoNamedCurve named_curve) {
+ return CreateEcImportAlgorithm(blink::WebCryptoAlgorithmIdEcdh, named_curve);
+}
+
+blink::WebCryptoAlgorithm CreateEcdhDeriveParams(
+ const blink::WebCryptoKey& public_key) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdEcdh,
+ new blink::WebCryptoEcdhKeyDeriveParams(public_key));
+}
+
+blink::WebCryptoAlgorithm CreateAesGcmDerivedKeyParams(
+ unsigned short length_bits) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdAesGcm,
+ new blink::WebCryptoAesDerivedKeyParams(length_bits));
+}
+
+// Helper that loads a "public_key" and "private_key" from the test data.
+bool ImportKeysFromTest(const base::DictionaryValue* test,
+ blink::WebCryptoKey* public_key,
+ blink::WebCryptoKey* private_key) {
+ // Import the public key.
+ const base::DictionaryValue* public_key_json = NULL;
+ EXPECT_TRUE(test->GetDictionary("public_key", &public_key_json));
+ blink::WebCryptoNamedCurve curve =
+ GetCurveNameFromDictionary(public_key_json);
+ EXPECT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk,
+ CryptoData(MakeJsonVector(*public_key_json)),
+ CreateEcdhImportAlgorithm(curve), true, 0, public_key));
+
+ // If the test didn't specify an error for private key import, that implies
+ // it expects success.
+ std::string expected_private_key_error = "Success";
+ test->GetString("private_key_error", &expected_private_key_error);
+
+ // Import the private key.
+ const base::DictionaryValue* private_key_json = NULL;
+ EXPECT_TRUE(test->GetDictionary("private_key", &private_key_json));
+ curve = GetCurveNameFromDictionary(private_key_json);
+ Status status = ImportKey(
+ blink::WebCryptoKeyFormatJwk,
+ CryptoData(MakeJsonVector(*private_key_json)),
+ CreateEcdhImportAlgorithm(curve), true,
+ blink::WebCryptoKeyUsageDeriveBits | blink::WebCryptoKeyUsageDeriveKey,
+ private_key);
+ EXPECT_EQ(expected_private_key_error, StatusToString(status));
+ return status.IsSuccess();
+}
+
+class WebCryptoEcdhTest : public WebCryptoTestBase {};
+
+TEST_F(WebCryptoEcdhTest, DeriveBitsKnownAnswer) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("ecdh.json", &tests));
+
+ 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));
+
+ // Import the keys.
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+ if (!ImportKeysFromTest(test, &public_key, &private_key))
+ continue;
+
+ // Now try to derive bytes.
+ std::vector<uint8_t> derived_bytes;
+ int length_bits = 0;
+ ASSERT_TRUE(test->GetInteger("length_bits", &length_bits));
+
+ // If the test didn't specify an error, that implies it expects success.
+ std::string expected_error = "Success";
+ test->GetString("error", &expected_error);
+
+ Status status = DeriveBits(CreateEcdhDeriveParams(public_key), private_key,
+ length_bits, &derived_bytes);
+ ASSERT_EQ(expected_error, StatusToString(status));
+ if (status.IsError())
+ continue;
+
+ std::vector<uint8_t> expected_bytes =
+ GetBytesFromHexString(test, "derived_bytes");
+
+ EXPECT_EQ(CryptoData(expected_bytes), CryptoData(derived_bytes));
+ }
+}
+
+// Loads up a test ECDH public and private key for P-521. The keys
+// come from different key pairs, and can be used for key derivation of up to
+// 528 bits.
+::testing::AssertionResult LoadTestKeys(blink::WebCryptoKey* public_key,
+ blink::WebCryptoKey* private_key) {
+ scoped_ptr<base::ListValue> tests;
+ if (!ReadJsonTestFileToList("ecdh.json", &tests))
+ return ::testing::AssertionFailure() << "Failed loading ecdh.json";
+
+ const base::DictionaryValue* test = NULL;
+ bool valid_p521_keys = false;
+ for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ SCOPED_TRACE(test_index);
+ EXPECT_TRUE(tests->GetDictionary(test_index, &test));
+ test->GetBoolean("valid_p521_keys", &valid_p521_keys);
+ if (valid_p521_keys)
+ break;
+ }
+ if (!valid_p521_keys) {
+ return ::testing::AssertionFailure()
+ << "The P-521 test are missing in ecdh.json";
+ }
+
+ ImportKeysFromTest(test, public_key, private_key);
+
+ EXPECT_EQ(blink::WebCryptoNamedCurveP521,
+ public_key->algorithm().ecParams()->namedCurve());
+
+ return ::testing::AssertionSuccess();
+}
+
+// Try deriving an AES key of length 129 bits.
+TEST_F(WebCryptoEcdhTest, DeriveKeyBadAesLength) {
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ ASSERT_TRUE(LoadTestKeys(&public_key, &base_key));
+
+ blink::WebCryptoKey derived_key;
+
+ ASSERT_EQ(Status::ErrorGetAesKeyLength(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm),
+ CreateAesGcmDerivedKeyParams(129), true,
+ blink::WebCryptoKeyUsageEncrypt, &derived_key));
+}
+
+// Try deriving an AES key of length 192 bits.
+TEST_F(WebCryptoEcdhTest, DeriveKeyUnsupportedAesLength) {
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ ASSERT_TRUE(LoadTestKeys(&public_key, &base_key));
+
+ blink::WebCryptoKey derived_key;
+
+ ASSERT_EQ(Status::ErrorAes192BitUnsupported(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm),
+ CreateAesGcmDerivedKeyParams(192), true,
+ blink::WebCryptoKeyUsageEncrypt, &derived_key));
+}
+
+// Try deriving an HMAC key of length 0 bits.
+TEST_F(WebCryptoEcdhTest, DeriveKeyZeroLengthHmac) {
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ ASSERT_TRUE(LoadTestKeys(&public_key, &base_key));
+
+ blink::WebCryptoKey derived_key;
+
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1, 0);
+
+ ASSERT_EQ(Status::ErrorGetHmacKeyLengthZero(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ import_algorithm, import_algorithm, true,
+ blink::WebCryptoKeyUsageSign, &derived_key));
+}
+
+// Derive an HMAC key of length 19 bits.
+TEST_F(WebCryptoEcdhTest, DeriveKeyHmac19Bits) {
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ ASSERT_TRUE(LoadTestKeys(&public_key, &base_key));
+
+ blink::WebCryptoKey derived_key;
+
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1, 19);
+
+ ASSERT_EQ(Status::Success(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ import_algorithm, import_algorithm, true,
+ blink::WebCryptoKeyUsageSign, &derived_key));
+
+ ASSERT_EQ(blink::WebCryptoAlgorithmIdHmac, derived_key.algorithm().id());
+ ASSERT_EQ(blink::WebCryptoAlgorithmIdSha1,
+ derived_key.algorithm().hmacParams()->hash().id());
+ ASSERT_EQ(19u, derived_key.algorithm().hmacParams()->lengthBits());
+
+ // Export the key and verify its contents.
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, derived_key, &raw_key));
+ EXPECT_EQ(3u, raw_key.size());
+ // The last 7 bits of the key should be zero.
+ EXPECT_EQ(0, raw_key[raw_key.size() - 1] & 0x1f);
+}
+
+// Derive an HMAC key with no specified length (just the hash of SHA-256).
+TEST_F(WebCryptoEcdhTest, DeriveKeyHmacSha256NoLength) {
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ ASSERT_TRUE(LoadTestKeys(&public_key, &base_key));
+
+ blink::WebCryptoKey derived_key;
+
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha256);
+
+ ASSERT_EQ(Status::Success(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ import_algorithm, import_algorithm, true,
+ blink::WebCryptoKeyUsageSign, &derived_key));
+
+ ASSERT_EQ(blink::WebCryptoAlgorithmIdHmac, derived_key.algorithm().id());
+ ASSERT_EQ(blink::WebCryptoAlgorithmIdSha256,
+ derived_key.algorithm().hmacParams()->hash().id());
+ ASSERT_EQ(512u, derived_key.algorithm().hmacParams()->lengthBits());
+
+ // Export the key and verify its contents.
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, derived_key, &raw_key));
+ EXPECT_EQ(64u, raw_key.size());
+}
+
+// Derive an HMAC key with no specified length (just the hash of SHA-512).
+//
+// This fails, because ECDH using P-521 can only generate 528 bits, however HMAC
+// SHA-512 requires 1024 bits.
+//
+// In practice, authors won't be directly generating keys from key agreement
+// schemes, as that is frequently insecure, and instead be using KDFs to expand
+// and generate keys. For simplicity of testing, however, test using an HMAC
+// key.
+TEST_F(WebCryptoEcdhTest, DeriveKeyHmacSha512NoLength) {
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ ASSERT_TRUE(LoadTestKeys(&public_key, &base_key));
+
+ blink::WebCryptoKey derived_key;
+
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha512);
+
+ ASSERT_EQ(Status::ErrorEcdhLengthTooBig(528),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ import_algorithm, import_algorithm, true,
+ blink::WebCryptoKeyUsageSign, &derived_key));
+}
+
+// Try deriving an AES key of length 128 bits.
+TEST_F(WebCryptoEcdhTest, DeriveKeyAes128) {
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ ASSERT_TRUE(LoadTestKeys(&public_key, &base_key));
+
+ blink::WebCryptoKey derived_key;
+
+ ASSERT_EQ(Status::Success(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm),
+ CreateAesGcmDerivedKeyParams(128), true,
+ blink::WebCryptoKeyUsageEncrypt, &derived_key));
+
+ ASSERT_EQ(blink::WebCryptoAlgorithmIdAesGcm, derived_key.algorithm().id());
+ ASSERT_EQ(128, derived_key.algorithm().aesParams()->lengthBits());
+
+ // Export the key and verify its contents.
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, derived_key, &raw_key));
+ EXPECT_EQ(16u, raw_key.size());
+}
+
+TEST_F(WebCryptoEcdhTest, ImportKeyEmptyUsage) {
+ blink::WebCryptoKey key;
+
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("ecdh.json", &tests));
+
+ const base::DictionaryValue* test;
+ ASSERT_TRUE(tests->GetDictionary(0, &test));
+
+ // Import the public key.
+ const base::DictionaryValue* public_key_json = NULL;
+ EXPECT_TRUE(test->GetDictionary("public_key", &public_key_json));
+ blink::WebCryptoNamedCurve curve =
+ GetCurveNameFromDictionary(public_key_json);
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk,
+ CryptoData(MakeJsonVector(*public_key_json)),
+ CreateEcdhImportAlgorithm(curve), true, 0, &key));
+ EXPECT_EQ(0, key.usages());
+
+ // Import the private key.
+ const base::DictionaryValue* private_key_json = NULL;
+ EXPECT_TRUE(test->GetDictionary("private_key", &private_key_json));
+ curve = GetCurveNameFromDictionary(private_key_json);
+ ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ ImportKey(blink::WebCryptoKeyFormatJwk,
+ CryptoData(MakeJsonVector(*private_key_json)),
+ CreateEcdhImportAlgorithm(curve), true, 0, &key));
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/ecdsa_openssl.cc b/chromium/components/webcrypto/algorithms/ecdsa.cc
index 53bbcbeb159..367e0f0ef4a 100644
--- a/chromium/components/webcrypto/openssl/ecdsa_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/ecdsa.cc
@@ -9,13 +9,12 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
+#include "components/webcrypto/algorithms/ec.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
-#include "components/webcrypto/openssl/ec_algorithm_openssl.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "crypto/secure_util.h"
@@ -33,8 +32,8 @@ Status GetPKeyAndDigest(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
EVP_PKEY** pkey,
const EVP_MD** digest) {
- *pkey = AsymKeyOpenSsl::Cast(key)->key();
- *digest = GetDigest(algorithm.ecdsaParams()->hash().id());
+ *pkey = GetEVP_PKEY(key);
+ *digest = GetDigest(algorithm.ecdsaParams()->hash());
if (!*digest)
return Status::ErrorUnsupported();
return Status::Success();
@@ -259,8 +258,8 @@ class EcdsaImplementation : public EcAlgorithm {
} // namespace
-AlgorithmImplementation* CreatePlatformEcdsaImplementation() {
- return new EcdsaImplementation;
+scoped_ptr<AlgorithmImplementation> CreateEcdsaImplementation() {
+ return make_scoped_ptr(new EcdsaImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/ecdsa_unittest.cc b/chromium/components/webcrypto/algorithms/ecdsa_unittest.cc
new file mode 100644
index 00000000000..4b2e6515ce6
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/ecdsa_unittest.cc
@@ -0,0 +1,349 @@
+// 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 "base/stl_util.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/jwk.h"
+#include "components/webcrypto/status.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+blink::WebCryptoAlgorithm CreateEcdsaKeyGenAlgorithm(
+ blink::WebCryptoNamedCurve named_curve) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdEcdsa,
+ new blink::WebCryptoEcKeyGenParams(named_curve));
+}
+
+blink::WebCryptoAlgorithm CreateEcdsaImportAlgorithm(
+ blink::WebCryptoNamedCurve named_curve) {
+ return CreateEcImportAlgorithm(blink::WebCryptoAlgorithmIdEcdsa, named_curve);
+}
+
+blink::WebCryptoAlgorithm CreateEcdsaAlgorithm(
+ blink::WebCryptoAlgorithmId hash_id) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdEcdsa,
+ new blink::WebCryptoEcdsaParams(CreateAlgorithm(hash_id)));
+}
+
+class WebCryptoEcdsaTest : public WebCryptoTestBase {};
+
+// Generates some ECDSA key pairs. Validates basic properties on the keys, and
+// ensures the serialized key (as JWK) is unique. This test does nothing to
+// ensure that the keys are otherwise usable (by trying to sign/verify with
+// them).
+TEST_F(WebCryptoEcdsaTest, GenerateKeyIsRandom) {
+ blink::WebCryptoNamedCurve named_curve = blink::WebCryptoNamedCurveP256;
+
+ std::vector<std::vector<uint8_t>> serialized_keys;
+
+ // Generate a small sample of keys.
+ for (int j = 0; j < 4; ++j) {
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ ASSERT_EQ(Status::Success(),
+ GenerateKeyPair(CreateEcdsaKeyGenAlgorithm(named_curve), true,
+ blink::WebCryptoKeyUsageSign, &public_key,
+ &private_key));
+
+ // Basic sanity checks on the generated key pair.
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
+ EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type());
+ EXPECT_EQ(named_curve, public_key.algorithm().ecParams()->namedCurve());
+ EXPECT_EQ(named_curve, private_key.algorithm().ecParams()->namedCurve());
+
+ // Export the key pair to JWK.
+ std::vector<uint8_t> key_bytes;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &key_bytes));
+ serialized_keys.push_back(key_bytes);
+
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, private_key, &key_bytes));
+ serialized_keys.push_back(key_bytes);
+ }
+
+ // Ensure all entries in the key sample set are unique. This is a simplistic
+ // estimate of whether the generated keys appear random.
+ EXPECT_FALSE(CopiesExist(serialized_keys));
+}
+
+TEST_F(WebCryptoEcdsaTest, GenerateKeyEmptyUsage) {
+ blink::WebCryptoNamedCurve named_curve = blink::WebCryptoNamedCurveP256;
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+ ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ GenerateKeyPair(CreateEcdsaKeyGenAlgorithm(named_curve), true, 0,
+ &public_key, &private_key));
+}
+
+// Verify that ECDSA signatures are probabilistic. Signing the same message two
+// times should yield different signatures. However both signatures should
+// verify correctly.
+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.
+ scoped_ptr<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));
+ blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(key_dict);
+ const base::DictionaryValue* key_jwk;
+ ASSERT_TRUE(key_dict->GetDictionary("jwk", &key_jwk));
+
+ blink::WebCryptoKey private_key;
+ ASSERT_EQ(
+ Status::Success(),
+ ImportKeyJwkFromDict(*key_jwk, CreateEcdsaImportAlgorithm(curve), true,
+ blink::WebCryptoKeyUsageSign, &private_key));
+
+ // Erase the "d" member so the private key JWK can be used to import the
+ // public key (WebCrypto doesn't provide a mechanism for importing a public
+ // key given a private key).
+ scoped_ptr<base::DictionaryValue> key_jwk_copy(key_jwk->DeepCopy());
+ key_jwk_copy->Remove("d", NULL);
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(*key_jwk_copy.get(),
+ CreateEcdsaImportAlgorithm(curve), true,
+ blink::WebCryptoKeyUsageVerify, &public_key));
+
+ // Sign twice
+ std::vector<uint8_t> message(10);
+ blink::WebCryptoAlgorithm algorithm =
+ CreateEcdsaAlgorithm(blink::WebCryptoAlgorithmIdSha1);
+
+ std::vector<uint8_t> signature1;
+ std::vector<uint8_t> signature2;
+ ASSERT_EQ(Status::Success(),
+ Sign(algorithm, private_key, CryptoData(message), &signature1));
+ ASSERT_EQ(Status::Success(),
+ Sign(algorithm, private_key, CryptoData(message), &signature2));
+
+ // The two signatures should be different.
+ EXPECT_NE(CryptoData(signature1), CryptoData(signature2));
+
+ // And both should be valid signatures which can be verified.
+ bool signature_matches;
+ ASSERT_EQ(Status::Success(),
+ Verify(algorithm, public_key, CryptoData(signature1),
+ CryptoData(message), &signature_matches));
+ EXPECT_TRUE(signature_matches);
+ ASSERT_EQ(Status::Success(),
+ Verify(algorithm, public_key, CryptoData(signature2),
+ CryptoData(message), &signature_matches));
+ EXPECT_TRUE(signature_matches);
+}
+
+// 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) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("ecdsa.json", &tests));
+
+ 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));
+
+ blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test);
+ blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
+ std::vector<uint8_t> key_data =
+ GetKeyDataFromJsonTestCase(test, key_format);
+
+ // If the test didn't specify an error, that implies it expects success.
+ std::string expected_error = "Success";
+ test->GetString("error", &expected_error);
+
+ // Import the public key.
+ blink::WebCryptoKey key;
+ Status status = ImportKey(key_format, CryptoData(key_data),
+ CreateEcdsaImportAlgorithm(curve), true,
+ blink::WebCryptoKeyUsageVerify, &key);
+ ASSERT_EQ(expected_error, StatusToString(status));
+ if (status.IsError())
+ continue;
+
+ // Basic sanity checks on the imported public key.
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type());
+ EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages());
+ EXPECT_EQ(curve, key.algorithm().ecParams()->namedCurve());
+
+ // Now try to verify the given message and signature.
+ std::vector<uint8_t> message = GetBytesFromHexString(test, "msg");
+ std::vector<uint8_t> signature = GetBytesFromHexString(test, "sig");
+ blink::WebCryptoAlgorithm hash = GetDigestAlgorithm(test, "hash");
+
+ bool verify_result;
+ status = Verify(CreateEcdsaAlgorithm(hash.id()), key, CryptoData(signature),
+ CryptoData(message), &verify_result);
+ ASSERT_EQ(expected_error, StatusToString(status));
+ if (status.IsError())
+ continue;
+
+ // If no error was expected, the verification's boolean must match
+ // "verify_result" for the test.
+ bool expected_result = false;
+ ASSERT_TRUE(test->GetBoolean("verify_result", &expected_result));
+ EXPECT_EQ(expected_result, verify_result);
+ }
+}
+
+// The test file may include either public or private keys. In order to import
+// them successfully, the correct usages need to be specified. This function
+// determines what usages to use for the key.
+blink::WebCryptoKeyUsageMask GetExpectedUsagesForKeyImport(
+ blink::WebCryptoKeyFormat key_format,
+ const base::DictionaryValue* test) {
+ blink::WebCryptoKeyUsageMask kPublicUsages = blink::WebCryptoKeyUsageVerify;
+ blink::WebCryptoKeyUsageMask kPrivateUsages = blink::WebCryptoKeyUsageSign;
+
+ switch (key_format) {
+ case blink::WebCryptoKeyFormatRaw:
+ case blink::WebCryptoKeyFormatSpki:
+ return kPublicUsages;
+ case blink::WebCryptoKeyFormatPkcs8:
+ return kPrivateUsages;
+ break;
+ case blink::WebCryptoKeyFormatJwk: {
+ const base::DictionaryValue* key = NULL;
+ if (!test->GetDictionary("key", &key))
+ ADD_FAILURE() << "Missing key property";
+ return key->HasKey("d") ? kPrivateUsages : kPublicUsages;
+ }
+ }
+
+ // Appease compiler.
+ return kPrivateUsages;
+}
+
+// Tests importing bad public/private keys in a variety of formats.
+TEST_F(WebCryptoEcdsaTest, ImportBadKeys) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("bad_ec_keys.json", &tests));
+
+ 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));
+
+ blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test);
+ blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
+ std::vector<uint8_t> key_data =
+ GetKeyDataFromJsonTestCase(test, key_format);
+ std::string expected_error;
+ ASSERT_TRUE(test->GetString("error", &expected_error));
+
+ blink::WebCryptoKey key;
+ Status status = ImportKey(
+ key_format, CryptoData(key_data), CreateEcdsaImportAlgorithm(curve),
+ true, GetExpectedUsagesForKeyImport(key_format, test), &key);
+ ASSERT_EQ(expected_error, StatusToString(status));
+ }
+}
+
+// Tests importing and exporting of EC private keys, using both JWK and PKCS8
+// formats.
+//
+// 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) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("ec_private_keys.json", &tests));
+
+ 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));
+
+ blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test);
+ const base::DictionaryValue* jwk_dict;
+ EXPECT_TRUE(test->GetDictionary("jwk", &jwk_dict));
+ std::vector<uint8_t> jwk_bytes = MakeJsonVector(*jwk_dict);
+ std::vector<uint8_t> pkcs8_bytes = GetBytesFromHexString(
+ test, test->HasKey("exported_pkcs8") ? "exported_pkcs8" : "pkcs8");
+
+ // -------------------------------------------------
+ // Test from JWK, and then export to {JWK, PKCS8}
+ // -------------------------------------------------
+
+ // Import the key using JWK
+ blink::WebCryptoKey key;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(jwk_bytes),
+ CreateEcdsaImportAlgorithm(curve), true,
+ blink::WebCryptoKeyUsageSign, &key));
+
+ // Export the key as JWK
+ std::vector<uint8_t> exported_bytes;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, key, &exported_bytes));
+
+ // NOTE: The exported bytes can't be directly compared to jwk_bytes because
+ // the exported JWK differs from the imported one. In particular it contains
+ // extra properties for extractability and key_ops.
+ //
+ // Verification is instead done by using the first exported JWK bytes as the
+ // expectation.
+ jwk_bytes = exported_bytes;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(jwk_bytes),
+ CreateEcdsaImportAlgorithm(curve), true,
+ blink::WebCryptoKeyUsageSign, &key));
+
+ // Export the key as JWK (again)
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, key, &exported_bytes));
+ EXPECT_EQ(CryptoData(jwk_bytes), CryptoData(exported_bytes));
+
+ // Export the key as PKCS8
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatPkcs8, key, &exported_bytes));
+ EXPECT_EQ(CryptoData(pkcs8_bytes), CryptoData(exported_bytes));
+
+ // -------------------------------------------------
+ // Test from PKCS8, and then export to {JWK, PKCS8}
+ // -------------------------------------------------
+
+ // The imported PKCS8 bytes may differ from the exported bytes (in the case
+ // where the publicKey was missing, it will be synthesized and written back
+ // during export).
+ std::vector<uint8_t> pkcs8_input_bytes = GetBytesFromHexString(
+ test, test->HasKey("original_pkcs8") ? "original_pkcs8" : "pkcs8");
+ CryptoData pkcs8_input_data(pkcs8_input_bytes.empty() ? pkcs8_bytes
+ : pkcs8_input_bytes);
+
+ // Import the key using PKCS8
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatPkcs8, pkcs8_input_data,
+ CreateEcdsaImportAlgorithm(curve), true,
+ blink::WebCryptoKeyUsageSign, &key));
+
+ // Export the key as PKCS8
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatPkcs8, key, &exported_bytes));
+ EXPECT_EQ(CryptoData(pkcs8_bytes), CryptoData(exported_bytes));
+
+ // Export the key as JWK
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, key, &exported_bytes));
+ EXPECT_EQ(CryptoData(jwk_bytes), CryptoData(exported_bytes));
+ }
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/hkdf_openssl.cc b/chromium/components/webcrypto/algorithms/hkdf.cc
index 9a1e2084bcb..0ccb857919c 100644
--- a/chromium/components/webcrypto/openssl/hkdf_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/hkdf.cc
@@ -8,11 +8,11 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
+#include "components/webcrypto/algorithms/secret_key_util.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
@@ -33,7 +33,7 @@ class HkdfImplementation : public AlgorithmImplementation {
blink::WebCryptoKeyUsageMask usages) const override {
if (format != blink::WebCryptoKeyFormatRaw)
return Status::ErrorUnsupportedImportKeyFormat();
- return CheckKeyCreationUsages(kValidUsages, usages, false);
+ return CheckSecretKeyCreationUsages(kValidUsages, usages);
}
Status ImportKeyRaw(const CryptoData& key_data,
@@ -58,7 +58,7 @@ class HkdfImplementation : public AlgorithmImplementation {
const blink::WebCryptoHkdfParams* params = algorithm.hkdfParams();
- const EVP_MD* digest_algorithm = GetDigest(params->hash().id());
+ const EVP_MD* digest_algorithm = GetDigest(params->hash());
if (!digest_algorithm)
return Status::ErrorUnsupported();
@@ -68,8 +68,7 @@ class HkdfImplementation : public AlgorithmImplementation {
// Algorithm dispatch checks that the algorithm in |base_key| matches
// |algorithm|.
- const std::vector<uint8_t>& raw_key =
- SymKeyOpenSsl::Cast(base_key)->raw_key_data();
+ const std::vector<uint8_t>& raw_key = GetSymmetricKeyData(base_key);
if (!HKDF(vector_as_array(derived_bytes), derived_bytes_len,
digest_algorithm, vector_as_array(&raw_key), raw_key.size(),
params->salt().data(), params->salt().size(),
@@ -86,13 +85,6 @@ class HkdfImplementation : public AlgorithmImplementation {
return Status::Success();
}
- Status SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const override {
- key_data->assign(SymKeyOpenSsl::Cast(key)->serialized_key_data());
- return Status::Success();
- }
-
Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
blink::WebCryptoKeyType type,
bool extractable,
@@ -113,8 +105,8 @@ class HkdfImplementation : public AlgorithmImplementation {
} // namespace
-AlgorithmImplementation* CreatePlatformHkdfImplementation() {
- return new HkdfImplementation;
+scoped_ptr<AlgorithmImplementation> CreateHkdfImplementation() {
+ return make_scoped_ptr(new HkdfImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/hmac_openssl.cc b/chromium/components/webcrypto/algorithms/hmac.cc
index 9962bfd8c55..28ef3a05ac2 100644
--- a/chromium/components/webcrypto/openssl/hmac_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/hmac.cc
@@ -5,14 +5,15 @@
#include <openssl/hmac.h>
#include "base/logging.h"
+#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
+#include "components/webcrypto/algorithms/secret_key_util.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/secure_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -22,6 +23,62 @@ namespace webcrypto {
namespace {
+Status GetDigestBlockSizeBits(const blink::WebCryptoAlgorithm& algorithm,
+ unsigned int* block_size_bits) {
+ const EVP_MD* md = GetDigest(algorithm);
+ if (!md)
+ return Status::ErrorUnsupported();
+ *block_size_bits = static_cast<unsigned int>(8 * EVP_MD_block_size(md));
+ return Status::Success();
+}
+
+// Gets the requested key length in bits for an HMAC import operation.
+Status GetHmacImportKeyLengthBits(
+ const blink::WebCryptoHmacImportParams* params,
+ unsigned int key_data_byte_length,
+ unsigned int* keylen_bits) {
+ if (key_data_byte_length == 0)
+ return Status::ErrorHmacImportEmptyKey();
+
+ // Make sure that the key data's length can be represented in bits without
+ // overflow.
+ base::CheckedNumeric<unsigned int> checked_keylen_bits(key_data_byte_length);
+ checked_keylen_bits *= 8;
+
+ if (!checked_keylen_bits.IsValid())
+ return Status::ErrorDataTooLarge();
+
+ unsigned int data_keylen_bits = checked_keylen_bits.ValueOrDie();
+
+ // Determine how many bits of the input to use.
+ *keylen_bits = data_keylen_bits;
+ if (params->hasLengthBits()) {
+ // The requested bit length must be:
+ // * No longer than the input data length
+ // * At most 7 bits shorter.
+ if (NumBitsToBytes(params->optionalLengthBits()) != key_data_byte_length)
+ return Status::ErrorHmacImportBadLength();
+ *keylen_bits = params->optionalLengthBits();
+ }
+
+ return Status::Success();
+}
+
+const char* GetJwkHmacAlgorithmName(blink::WebCryptoAlgorithmId hash) {
+ switch (hash) {
+ case blink::WebCryptoAlgorithmIdSha1:
+ return "HS1";
+ case blink::WebCryptoAlgorithmIdSha256:
+ return "HS256";
+ case blink::WebCryptoAlgorithmIdSha384:
+ return "HS384";
+ case blink::WebCryptoAlgorithmIdSha512:
+ return "HS512";
+ default:
+ return NULL;
+ }
+}
+
const blink::WebCryptoKeyUsageMask kAllKeyUsages =
blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify;
@@ -31,7 +88,7 @@ Status SignHmac(const std::vector<uint8_t>& raw_key,
std::vector<uint8_t>* buffer) {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- const EVP_MD* digest_algorithm = GetDigest(hash.id());
+ const EVP_MD* digest_algorithm = GetDigest(hash);
if (!digest_algorithm)
return Status::ErrorUnsupported();
size_t hmac_expected_length = EVP_MD_size(digest_algorithm);
@@ -58,7 +115,7 @@ class HmacImplementation : public AlgorithmImplementation {
bool extractable,
blink::WebCryptoKeyUsageMask usages,
GenerateKeyResult* result) const override {
- Status status = CheckKeyCreationUsages(kAllKeyUsages, usages, false);
+ Status status = CheckSecretKeyCreationUsages(kAllKeyUsages, usages);
if (status.IsError())
return status;
@@ -66,9 +123,16 @@ class HmacImplementation : public AlgorithmImplementation {
algorithm.hmacKeyGenParams();
unsigned int keylen_bits = 0;
- status = GetHmacKeyGenLengthInBits(params, &keylen_bits);
- if (status.IsError())
- return status;
+ if (params->hasLengthBits()) {
+ keylen_bits = params->optionalLengthBits();
+ // Zero-length HMAC keys are disallowed by the spec.
+ if (keylen_bits == 0)
+ return Status::ErrorGenerateHmacKeyLengthZero();
+ } else {
+ status = GetDigestBlockSizeBits(params->hash(), &keylen_bits);
+ if (status.IsError())
+ return status;
+ }
return GenerateWebCryptoSecretKey(blink::WebCryptoKeyAlgorithm::createHmac(
params->hash().id(), keylen_bits),
@@ -81,7 +145,7 @@ class HmacImplementation : public AlgorithmImplementation {
switch (format) {
case blink::WebCryptoKeyFormatRaw:
case blink::WebCryptoKeyFormatJwk:
- return CheckKeyCreationUsages(kAllKeyUsages, usages, false);
+ return CheckSecretKeyCreationUsages(kAllKeyUsages, usages);
default:
return Status::ErrorUnsupportedImportKeyFormat();
}
@@ -130,8 +194,12 @@ class HmacImplementation : public AlgorithmImplementation {
return Status::ErrorUnexpected();
std::vector<uint8_t> raw_data;
- Status status = ReadSecretKeyJwk(key_data, algorithm_name, extractable,
- usages, &raw_data);
+ JwkReader jwk;
+ Status status = ReadSecretKeyNoExpectedAlgJwk(key_data, extractable, usages,
+ &raw_data, &jwk);
+ if (status.IsError())
+ return status;
+ status = jwk.VerifyAlg(algorithm_name);
if (status.IsError())
return status;
@@ -141,14 +209,13 @@ class HmacImplementation : public AlgorithmImplementation {
Status ExportKeyRaw(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const override {
- *buffer = SymKeyOpenSsl::Cast(key)->raw_key_data();
+ *buffer = GetSymmetricKeyData(key);
return Status::Success();
}
Status ExportKeyJwk(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const override {
- SymKeyOpenSsl* sym_key = SymKeyOpenSsl::Cast(key);
- const std::vector<uint8_t>& raw_data = sym_key->raw_key_data();
+ const std::vector<uint8_t>& raw_data = GetSymmetricKeyData(key);
const char* algorithm_name =
GetJwkHmacAlgorithmName(key.algorithm().hmacParams()->hash().id());
@@ -168,8 +235,7 @@ class HmacImplementation : public AlgorithmImplementation {
const blink::WebCryptoAlgorithm& hash =
key.algorithm().hmacParams()->hash();
- return SignHmac(SymKeyOpenSsl::Cast(key)->raw_key_data(), hash, data,
- buffer);
+ return SignHmac(GetSymmetricKeyData(key), hash, data, buffer);
}
Status Verify(const blink::WebCryptoAlgorithm& algorithm,
@@ -192,13 +258,6 @@ class HmacImplementation : public AlgorithmImplementation {
return Status::Success();
}
- Status SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const override {
- key_data->assign(SymKeyOpenSsl::Cast(key)->serialized_key_data());
- return Status::Success();
- }
-
Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
blink::WebCryptoKeyType type,
bool extractable,
@@ -212,14 +271,25 @@ class HmacImplementation : public AlgorithmImplementation {
Status GetKeyLength(const blink::WebCryptoAlgorithm& key_length_algorithm,
bool* has_length_bits,
unsigned int* length_bits) const override {
- return GetHmacKeyLength(key_length_algorithm, has_length_bits, length_bits);
+ const blink::WebCryptoHmacImportParams* params =
+ key_length_algorithm.hmacImportParams();
+
+ *has_length_bits = true;
+ if (params->hasLengthBits()) {
+ *length_bits = params->optionalLengthBits();
+ if (*length_bits == 0)
+ return Status::ErrorGetHmacKeyLengthZero();
+ return Status::Success();
+ }
+
+ return GetDigestBlockSizeBits(params->hash(), length_bits);
}
};
} // namespace
-AlgorithmImplementation* CreatePlatformHmacImplementation() {
- return new HmacImplementation;
+scoped_ptr<AlgorithmImplementation> CreateHmacImplementation() {
+ return make_scoped_ptr(new HmacImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/hmac_unittest.cc b/chromium/components/webcrypto/algorithms/hmac_unittest.cc
new file mode 100644
index 00000000000..4c8a67aa513
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/hmac_unittest.cc
@@ -0,0 +1,602 @@
+// 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 "base/logging.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+// Creates an HMAC algorithm whose parameters struct is compatible with key
+// generation. It is an error to call this with a hash_id that is not a SHA*.
+// The key_length_bits parameter is optional, with zero meaning unspecified.
+blink::WebCryptoAlgorithm CreateHmacKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmId hash_id,
+ unsigned int key_length_bits) {
+ DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
+ // key_length_bytes == 0 means unspecified
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdHmac,
+ new blink::WebCryptoHmacKeyGenParams(
+ CreateAlgorithm(hash_id), (key_length_bits != 0), key_length_bits));
+}
+
+blink::WebCryptoAlgorithm CreateHmacImportAlgorithmWithLength(
+ blink::WebCryptoAlgorithmId hash_id,
+ unsigned int length_bits) {
+ DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdHmac,
+ new blink::WebCryptoHmacImportParams(CreateAlgorithm(hash_id), true,
+ length_bits));
+}
+
+class WebCryptoHmacTest : public WebCryptoTestBase {};
+
+TEST_F(WebCryptoHmacTest, HMACSampleSets) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("hmac.json", &tests));
+ 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));
+
+ blink::WebCryptoAlgorithm test_hash = GetDigestAlgorithm(test, "hash");
+ const std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key");
+ const std::vector<uint8_t> test_message =
+ GetBytesFromHexString(test, "message");
+ const std::vector<uint8_t> test_mac = GetBytesFromHexString(test, "mac");
+
+ blink::WebCryptoAlgorithm algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac);
+
+ blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithmNoLength(test_hash.id());
+
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw(
+ test_key, import_algorithm,
+ blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify);
+
+ EXPECT_EQ(test_hash.id(), key.algorithm().hmacParams()->hash().id());
+ EXPECT_EQ(test_key.size() * 8, key.algorithm().hmacParams()->lengthBits());
+
+ // Verify exported raw key is identical to the imported data
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ EXPECT_BYTES_EQ(test_key, raw_key);
+
+ std::vector<uint8_t> output;
+
+ ASSERT_EQ(Status::Success(),
+ Sign(algorithm, key, CryptoData(test_message), &output));
+
+ EXPECT_BYTES_EQ(test_mac, output);
+
+ bool signature_match = false;
+ EXPECT_EQ(Status::Success(),
+ Verify(algorithm, key, CryptoData(output),
+ CryptoData(test_message), &signature_match));
+ EXPECT_TRUE(signature_match);
+
+ // Ensure truncated signature does not verify by passing one less byte.
+ EXPECT_EQ(Status::Success(),
+ Verify(algorithm, key,
+ CryptoData(vector_as_array(&output),
+ static_cast<unsigned int>(output.size()) - 1),
+ CryptoData(test_message), &signature_match));
+ EXPECT_FALSE(signature_match);
+
+ // Ensure truncated signature does not verify by passing no bytes.
+ EXPECT_EQ(Status::Success(),
+ Verify(algorithm, key, CryptoData(), CryptoData(test_message),
+ &signature_match));
+ EXPECT_FALSE(signature_match);
+
+ // Ensure extra long signature does not cause issues and fails.
+ const unsigned char kLongSignature[1024] = {0};
+ EXPECT_EQ(Status::Success(),
+ Verify(algorithm, key,
+ CryptoData(kLongSignature, sizeof(kLongSignature)),
+ CryptoData(test_message), &signature_match));
+ EXPECT_FALSE(signature_match);
+ }
+}
+
+TEST_F(WebCryptoHmacTest, GenerateKeyIsRandom) {
+ // Generate a small sample of HMAC keys.
+ std::vector<std::vector<uint8_t>> keys;
+ for (int i = 0; i < 16; ++i) {
+ std::vector<uint8_t> key_bytes;
+ blink::WebCryptoKey key;
+ blink::WebCryptoAlgorithm algorithm =
+ CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha1, 512);
+ ASSERT_EQ(
+ Status::Success(),
+ GenerateSecretKey(algorithm, true, blink::WebCryptoKeyUsageSign, &key));
+ EXPECT_FALSE(key.isNull());
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha1,
+ key.algorithm().hmacParams()->hash().id());
+ EXPECT_EQ(512u, key.algorithm().hmacParams()->lengthBits());
+
+ std::vector<uint8_t> raw_key;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ EXPECT_EQ(64U, raw_key.size());
+ keys.push_back(raw_key);
+ }
+ // Ensure all entries in the key sample set are unique. This is a simplistic
+ // estimate of whether the generated keys appear random.
+ EXPECT_FALSE(CopiesExist(keys));
+}
+
+// If the key length is not provided, then the block size is used.
+TEST_F(WebCryptoHmacTest, GenerateKeyNoLengthSha1) {
+ blink::WebCryptoKey key;
+ blink::WebCryptoAlgorithm algorithm =
+ CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha1, 0);
+ ASSERT_EQ(
+ Status::Success(),
+ GenerateSecretKey(algorithm, true, blink::WebCryptoKeyUsageSign, &key));
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha1,
+ key.algorithm().hmacParams()->hash().id());
+ EXPECT_EQ(512u, key.algorithm().hmacParams()->lengthBits());
+ std::vector<uint8_t> raw_key;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ EXPECT_EQ(64U, raw_key.size());
+}
+
+// If the key length is not provided, then the block size is used.
+TEST_F(WebCryptoHmacTest, GenerateKeyNoLengthSha512) {
+ blink::WebCryptoKey key;
+ blink::WebCryptoAlgorithm algorithm =
+ CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha512, 0);
+ ASSERT_EQ(
+ Status::Success(),
+ GenerateSecretKey(algorithm, true, blink::WebCryptoKeyUsageSign, &key));
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha512,
+ key.algorithm().hmacParams()->hash().id());
+ EXPECT_EQ(1024u, key.algorithm().hmacParams()->lengthBits());
+ std::vector<uint8_t> raw_key;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ EXPECT_EQ(128U, raw_key.size());
+}
+
+TEST_F(WebCryptoHmacTest, GenerateKeyEmptyUsage) {
+ blink::WebCryptoKey key;
+ blink::WebCryptoAlgorithm algorithm =
+ CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha512, 0);
+ ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ GenerateSecretKey(algorithm, true, 0, &key));
+}
+
+// Generate a 1 bit key. The exported key is 1 byte long, and 7 of the bits are
+// guaranteed to be zero.
+TEST_F(WebCryptoHmacTest, Generate1BitKey) {
+ blink::WebCryptoKey key;
+ blink::WebCryptoAlgorithm algorithm =
+ CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha1, 1);
+
+ ASSERT_EQ(
+ Status::Success(),
+ GenerateSecretKey(algorithm, true, blink::WebCryptoKeyUsageSign, &key));
+ EXPECT_EQ(1u, key.algorithm().hmacParams()->lengthBits());
+
+ std::vector<uint8_t> raw_key;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ ASSERT_EQ(1U, raw_key.size());
+
+ EXPECT_FALSE(raw_key[0] & 0x7F);
+}
+
+TEST_F(WebCryptoHmacTest, ImportKeyEmptyUsage) {
+ blink::WebCryptoKey key;
+ std::string key_raw_hex_in = "025a8cf3f08b4f6c5f33bbc76a471939";
+ EXPECT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(HexStringToBytes(key_raw_hex_in)),
+ CreateHmacImportAlgorithmNoLength(
+ blink::WebCryptoAlgorithmIdSha1),
+ true, 0, &key));
+}
+
+TEST_F(WebCryptoHmacTest, ImportKeyJwkKeyOpsSignVerify) {
+ blink::WebCryptoKey key;
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
+ base::ListValue* key_ops = new base::ListValue;
+ dict.Set("key_ops", key_ops); // Takes ownership.
+
+ key_ops->AppendString("sign");
+
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(dict, CreateHmacImportAlgorithmNoLength(
+ blink::WebCryptoAlgorithmIdSha256),
+ false, blink::WebCryptoKeyUsageSign, &key));
+
+ EXPECT_EQ(blink::WebCryptoKeyUsageSign, key.usages());
+
+ key_ops->AppendString("verify");
+
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(dict, CreateHmacImportAlgorithmNoLength(
+ blink::WebCryptoAlgorithmIdSha256),
+ false, blink::WebCryptoKeyUsageVerify, &key));
+
+ EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages());
+}
+
+// Test 'use' inconsistent with 'key_ops'.
+TEST_F(WebCryptoHmacTest, ImportKeyJwkUseInconsisteWithKeyOps) {
+ blink::WebCryptoKey key;
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
+ base::ListValue* key_ops = new base::ListValue;
+ dict.Set("key_ops", key_ops); // Takes ownership.
+
+ dict.SetString("alg", "HS256");
+ dict.SetString("use", "sig");
+ key_ops->AppendString("sign");
+ key_ops->AppendString("verify");
+ key_ops->AppendString("encrypt");
+ EXPECT_EQ(
+ Status::ErrorJwkUseAndKeyopsInconsistent(),
+ ImportKeyJwkFromDict(
+ dict,
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha256),
+ false, blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
+ &key));
+}
+
+// Test JWK composite 'sig' use
+TEST_F(WebCryptoHmacTest, ImportKeyJwkUseSig) {
+ blink::WebCryptoKey key;
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
+
+ dict.SetString("use", "sig");
+ EXPECT_EQ(
+ Status::Success(),
+ ImportKeyJwkFromDict(
+ dict,
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha256),
+ false, blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
+ &key));
+
+ EXPECT_EQ(blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
+ key.usages());
+}
+
+TEST_F(WebCryptoHmacTest, ImportJwkInputConsistency) {
+ // The Web Crypto spec says that if a JWK value is present, but is
+ // inconsistent with the input value, the operation must fail.
+
+ // Consistency rules when JWK value is not present: Inputs should be used.
+ blink::WebCryptoKey key;
+ bool extractable = false;
+ blink::WebCryptoAlgorithm algorithm =
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha256);
+ blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageVerify;
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
+ std::vector<uint8_t> json_vec = MakeJsonVector(dict);
+ EXPECT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(json_vec),
+ algorithm, extractable, usages, &key));
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ EXPECT_EQ(extractable, key.extractable());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256,
+ key.algorithm().hmacParams()->hash().id());
+ EXPECT_EQ(320u, key.algorithm().hmacParams()->lengthBits());
+ EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages());
+ key = blink::WebCryptoKey::createNull();
+
+ // Consistency rules when JWK value exists: Fail if inconsistency is found.
+
+ // Pass: All input values are consistent with the JWK values.
+ dict.Clear();
+ dict.SetString("kty", "oct");
+ dict.SetString("alg", "HS256");
+ dict.SetString("use", "sig");
+ dict.SetBoolean("ext", false);
+ dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
+ json_vec = MakeJsonVector(dict);
+ EXPECT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(json_vec),
+ algorithm, extractable, usages, &key));
+
+ // Extractable cases:
+ // 1. input=T, JWK=F ==> fail (inconsistent)
+ // 4. input=F, JWK=F ==> pass, result extractable is F
+ // 2. input=T, JWK=T ==> pass, result extractable is T
+ // 3. input=F, JWK=T ==> pass, result extractable is F
+ EXPECT_EQ(Status::ErrorJwkExtInconsistent(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(json_vec),
+ algorithm, true, usages, &key));
+ EXPECT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(json_vec),
+ algorithm, false, usages, &key));
+ EXPECT_FALSE(key.extractable());
+ dict.SetBoolean("ext", true);
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(dict, algorithm, true, usages, &key));
+ EXPECT_TRUE(key.extractable());
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
+ EXPECT_FALSE(key.extractable());
+ dict.SetBoolean("ext", true); // restore previous value
+
+ // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value
+ // (HMAC SHA256).
+ dict.Clear();
+ dict.SetString("kty", "oct");
+ dict.SetString("alg", "HS256");
+ dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
+ EXPECT_EQ(Status::ErrorJwkAlgorithmInconsistent(),
+ ImportKeyJwkFromDict(
+ dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
+ extractable, blink::WebCryptoKeyUsageEncrypt, &key));
+ // Fail: Input usage (encrypt) is inconsistent with JWK value (use=sig).
+ EXPECT_EQ(Status::ErrorJwkUseInconsistent(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(json_vec),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
+ extractable, blink::WebCryptoKeyUsageEncrypt, &key));
+
+ // Fail: Input algorithm (HMAC SHA1) is inconsistent with JWK value
+ // (HMAC SHA256).
+ EXPECT_EQ(Status::ErrorJwkAlgorithmInconsistent(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(json_vec),
+ CreateHmacImportAlgorithmNoLength(
+ blink::WebCryptoAlgorithmIdSha1),
+ extractable, usages, &key));
+
+ // Pass: JWK alg missing but input algorithm specified: use input value
+ dict.Remove("alg", NULL);
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(dict, CreateHmacImportAlgorithmNoLength(
+ blink::WebCryptoAlgorithmIdSha256),
+ extractable, usages, &key));
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id());
+ dict.SetString("alg", "HS256");
+
+ // Fail: Input usages (encrypt) is not a subset of the JWK value
+ // (sign|verify). Moreover "encrypt" is not a valid usage for HMAC.
+ EXPECT_EQ(
+ Status::ErrorCreateKeyBadUsages(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(json_vec), algorithm,
+ extractable, blink::WebCryptoKeyUsageEncrypt, &key));
+
+ // Fail: Input usages (encrypt|sign|verify) is not a subset of the JWK
+ // value (sign|verify). Moreover "encrypt" is not a valid usage for HMAC.
+ usages = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign |
+ blink::WebCryptoKeyUsageVerify;
+ EXPECT_EQ(Status::ErrorCreateKeyBadUsages(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(json_vec),
+ algorithm, extractable, usages, &key));
+
+ // TODO(padolph): kty vs alg consistency tests: Depending on the kty value,
+ // only certain alg values are permitted. For example, when kty = "RSA" alg
+ // must be of the RSA family, or when kty = "oct" alg must be symmetric
+ // algorithm.
+
+ // TODO(padolph): key_ops consistency tests
+}
+
+TEST_F(WebCryptoHmacTest, ImportJwkHappy) {
+ // This test verifies the happy path of JWK import, including the application
+ // of the imported key material.
+
+ blink::WebCryptoKey key;
+ bool extractable = false;
+ blink::WebCryptoAlgorithm algorithm =
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha256);
+ blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign;
+
+ // Import a symmetric key JWK and HMAC-SHA256 sign()
+ // Uses the first SHA256 test vector from the HMAC sample set above.
+
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("alg", "HS256");
+ dict.SetString("use", "sig");
+ dict.SetBoolean("ext", false);
+ dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
+
+ ASSERT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(dict, algorithm, extractable, usages, &key));
+
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256,
+ key.algorithm().hmacParams()->hash().id());
+
+ const std::vector<uint8_t> message_raw = HexStringToBytes(
+ "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a"
+ "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92"
+ "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f"
+ "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e");
+
+ std::vector<uint8_t> output;
+
+ ASSERT_EQ(Status::Success(),
+ Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), key,
+ CryptoData(message_raw), &output));
+
+ const std::string mac_raw =
+ "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b";
+
+ EXPECT_BYTES_EQ_HEX(mac_raw, output);
+
+ // TODO(padolph): Import an RSA public key JWK and use it
+}
+
+TEST_F(WebCryptoHmacTest, ImportExportJwk) {
+ // HMAC SHA-1
+ ImportExportJwkSymmetricKey(
+ 256, CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha1),
+ blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, "HS1");
+
+ // HMAC SHA-384
+ ImportExportJwkSymmetricKey(
+ 384, CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha384),
+ blink::WebCryptoKeyUsageSign, "HS384");
+
+ // HMAC SHA-512
+ ImportExportJwkSymmetricKey(
+ 512, CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha512),
+ blink::WebCryptoKeyUsageVerify, "HS512");
+}
+
+TEST_F(WebCryptoHmacTest, ExportJwkEmptyKey) {
+ blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign;
+
+ // Importing empty HMAC key is no longer allowed. However such a key can be
+ // created via de-serialization.
+ blink::WebCryptoKey key;
+ ASSERT_TRUE(DeserializeKeyForClone(blink::WebCryptoKeyAlgorithm::createHmac(
+ blink::WebCryptoAlgorithmIdSha1, 0),
+ blink::WebCryptoKeyTypeSecret, true,
+ usages, CryptoData(), &key));
+
+ // Export the key in JWK format and validate.
+ std::vector<uint8_t> json;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, key, &json));
+ EXPECT_TRUE(VerifySecretJwk(json, "HS1", "", usages));
+
+ // Now try re-importing the JWK key.
+ key = blink::WebCryptoKey::createNull();
+ EXPECT_EQ(Status::ErrorHmacImportEmptyKey(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(json),
+ CreateHmacImportAlgorithmNoLength(
+ blink::WebCryptoAlgorithmIdSha1),
+ true, usages, &key));
+}
+
+// Imports an HMAC key contaning no byte data.
+TEST_F(WebCryptoHmacTest, ImportRawEmptyKey) {
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha1);
+
+ blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign;
+ blink::WebCryptoKey key;
+
+ ASSERT_EQ(Status::ErrorHmacImportEmptyKey(),
+ ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(),
+ import_algorithm, true, usages, &key));
+}
+
+// Imports an HMAC key contaning 1 byte data, however the length was set to 0.
+TEST_F(WebCryptoHmacTest, ImportRawKeyWithZeroLength) {
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1, 0);
+
+ blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign;
+ blink::WebCryptoKey key;
+
+ std::vector<uint8_t> key_data(1);
+ ASSERT_EQ(Status::ErrorHmacImportBadLength(),
+ ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(key_data),
+ import_algorithm, true, usages, &key));
+}
+
+// Import a huge hmac key (UINT_MAX bytes). This will fail before actually
+// reading the bytes, as the key is too large.
+TEST_F(WebCryptoHmacTest, ImportRawKeyTooLarge) {
+ CryptoData big_data(NULL, UINT_MAX); // Invalid data of big length.
+
+ blink::WebCryptoKey key;
+ EXPECT_EQ(Status::ErrorDataTooLarge(),
+ ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(big_data),
+ CreateHmacImportAlgorithmNoLength(
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageSign, &key));
+}
+
+// Import an HMAC key with 120 bits of data, however request 128 bits worth.
+TEST_F(WebCryptoHmacTest, ImportRawKeyLengthTooLarge) {
+ blink::WebCryptoKey key;
+ EXPECT_EQ(Status::ErrorHmacImportBadLength(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(std::vector<uint8_t>(15)),
+ CreateHmacImportAlgorithmWithLength(
+ blink::WebCryptoAlgorithmIdSha1, 128),
+ true, blink::WebCryptoKeyUsageSign, &key));
+}
+
+// Import an HMAC key with 128 bits of data, however request 120 bits worth.
+TEST_F(WebCryptoHmacTest, ImportRawKeyLengthTooSmall) {
+ blink::WebCryptoKey key;
+ EXPECT_EQ(Status::ErrorHmacImportBadLength(),
+ ImportKey(blink::WebCryptoKeyFormatRaw,
+ CryptoData(std::vector<uint8_t>(16)),
+ CreateHmacImportAlgorithmWithLength(
+ blink::WebCryptoAlgorithmIdSha1, 120),
+ true, blink::WebCryptoKeyUsageSign, &key));
+}
+
+// Import an HMAC key with 16 bits of data and request a 12 bit key, using the
+// "raw" format.
+TEST_F(WebCryptoHmacTest, ImportRawKeyTruncation) {
+ const std::vector<uint8_t> data = HexStringToBytes("b1ff");
+
+ blink::WebCryptoKey key;
+ EXPECT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(data),
+ CreateHmacImportAlgorithmWithLength(
+ blink::WebCryptoAlgorithmIdSha1, 12),
+ true, blink::WebCryptoKeyUsageSign, &key));
+
+ // On export the last 4 bits has been set to zero.
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ EXPECT_BYTES_EQ(HexStringToBytes("b1f0"), raw_key);
+}
+
+// The same test as above, but using the JWK format.
+TEST_F(WebCryptoHmacTest, ImportJwkKeyTruncation) {
+ base::DictionaryValue dict;
+ dict.SetString("kty", "oct");
+ dict.SetString("k", "sf8"); // 0xB1FF
+
+ blink::WebCryptoKey key;
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(dict, CreateHmacImportAlgorithmWithLength(
+ blink::WebCryptoAlgorithmIdSha1, 12),
+ true, blink::WebCryptoKeyUsageSign, &key));
+
+ // On export the last 4 bits has been set to zero.
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ EXPECT_BYTES_EQ(HexStringToBytes("b1f0"), raw_key);
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/pbkdf2_openssl.cc b/chromium/components/webcrypto/algorithms/pbkdf2.cc
index c4ce8466ba6..b5cf5ca0229 100644
--- a/chromium/components/webcrypto/openssl/pbkdf2_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/pbkdf2.cc
@@ -4,11 +4,11 @@
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
+#include "components/webcrypto/algorithms/secret_key_util.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
@@ -29,7 +29,7 @@ class Pbkdf2Implementation : public AlgorithmImplementation {
blink::WebCryptoKeyUsageMask usages) const override {
switch (format) {
case blink::WebCryptoKeyFormatRaw:
- return CheckKeyCreationUsages(kAllKeyUsages, usages, false);
+ return CheckSecretKeyCreationUsages(kAllKeyUsages, usages);
default:
return Status::ErrorUnsupportedImportKeyFormat();
}
@@ -63,16 +63,14 @@ class Pbkdf2Implementation : public AlgorithmImplementation {
const blink::WebCryptoPbkdf2Params* params = algorithm.pbkdf2Params();
- const blink::WebCryptoAlgorithm& hash = params->hash();
- const EVP_MD* digest_algorithm = GetDigest(hash.id());
+ const EVP_MD* digest_algorithm = GetDigest(params->hash());
if (!digest_algorithm)
return Status::ErrorUnsupported();
unsigned int keylen_bytes = optional_length_bits / 8;
derived_bytes->resize(keylen_bytes);
- const std::vector<uint8_t>& password =
- SymKeyOpenSsl::Cast(base_key)->raw_key_data();
+ const std::vector<uint8_t>& password = GetSymmetricKeyData(base_key);
if (!PKCS5_PBKDF2_HMAC(
reinterpret_cast<const char*>(vector_as_array(&password)),
@@ -84,13 +82,6 @@ class Pbkdf2Implementation : public AlgorithmImplementation {
return Status::Success();
}
- Status SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const override {
- key_data->assign(SymKeyOpenSsl::Cast(key)->serialized_key_data());
- return Status::Success();
- }
-
Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
blink::WebCryptoKeyType type,
bool extractable,
@@ -111,8 +102,8 @@ class Pbkdf2Implementation : public AlgorithmImplementation {
} // namespace
-AlgorithmImplementation* CreatePlatformPbkdf2Implementation() {
- return new Pbkdf2Implementation;
+scoped_ptr<AlgorithmImplementation> CreatePbkdf2Implementation() {
+ return make_scoped_ptr(new Pbkdf2Implementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc b/chromium/components/webcrypto/algorithms/rsa.cc
index 9857a071fc6..892a5a0ec13 100644
--- a/chromium/components/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/rsa.cc
@@ -2,19 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/webcrypto/openssl/rsa_hashed_algorithm_openssl.h"
+#include "components/webcrypto/algorithms/rsa.h"
#include <openssl/evp.h>
#include "base/logging.h"
#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/asymmetric_key_util.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -24,6 +24,106 @@ namespace webcrypto {
namespace {
+// Describes the RSA components for a parsed key. The names of the properties
+// correspond with those from the JWK spec. Note that Chromium's WebCrypto
+// implementation does not support multi-primes, so there is no parsed field
+// for "oth".
+struct JwkRsaInfo {
+ bool is_private_key = false;
+ std::string n;
+ std::string e;
+ std::string d;
+ std::string p;
+ std::string q;
+ std::string dp;
+ std::string dq;
+ std::string qi;
+};
+
+// Parses a UTF-8 encoded JWK (key_data), and extracts the RSA components to
+// |*result|. Returns Status::Success() on success, otherwise an error.
+// In order for this to succeed:
+// * expected_alg must match the JWK's "alg", if present.
+// * expected_extractable must be consistent with the JWK's "ext", if
+// present.
+// * expected_usages must be a subset of the JWK's "key_ops" if present.
+Status ReadRsaKeyJwk(const CryptoData& key_data,
+ const std::string& expected_alg,
+ bool expected_extractable,
+ blink::WebCryptoKeyUsageMask expected_usages,
+ JwkRsaInfo* result) {
+ JwkReader jwk;
+ Status status = jwk.Init(key_data, expected_extractable, expected_usages,
+ "RSA", expected_alg);
+ if (status.IsError())
+ return status;
+
+ // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry
+ // in the JWK, while an RSA private key must have those, plus at least a "d"
+ // (private exponent) entry.
+ // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
+ // section 6.3.
+ status = jwk.GetBigInteger("n", &result->n);
+ if (status.IsError())
+ return status;
+ status = jwk.GetBigInteger("e", &result->e);
+ if (status.IsError())
+ return status;
+
+ result->is_private_key = jwk.HasMember("d");
+ if (!result->is_private_key)
+ return Status::Success();
+
+ status = jwk.GetBigInteger("d", &result->d);
+ if (status.IsError())
+ return status;
+
+ // The "p", "q", "dp", "dq", and "qi" properties are optional in the JWA
+ // spec. However they are required by Chromium's WebCrypto implementation.
+
+ status = jwk.GetBigInteger("p", &result->p);
+ if (status.IsError())
+ return status;
+
+ status = jwk.GetBigInteger("q", &result->q);
+ if (status.IsError())
+ return status;
+
+ status = jwk.GetBigInteger("dp", &result->dp);
+ if (status.IsError())
+ return status;
+
+ status = jwk.GetBigInteger("dq", &result->dq);
+ if (status.IsError())
+ return status;
+
+ status = jwk.GetBigInteger("qi", &result->qi);
+ if (status.IsError())
+ return status;
+
+ return Status::Success();
+}
+
+// Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros,
+// to unsigned int.
+bool BigIntegerToUint(const uint8_t* data,
+ size_t data_size,
+ unsigned int* result) {
+ if (data_size == 0)
+ return false;
+
+ *result = 0;
+ for (size_t i = 0; i < data_size; ++i) {
+ size_t reverse_i = data_size - i - 1;
+
+ if (reverse_i >= sizeof(*result) && data[i])
+ return false; // Too large for a uint.
+
+ *result |= data[i] << 8 * reverse_i;
+ }
+ return true;
+}
+
// Creates a blink::WebCryptoAlgorithm having the modulus length and public
// exponent of |key|.
Status CreateRsaHashedKeyAlgorithm(
@@ -110,8 +210,7 @@ Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm,
return Status::OperationError();
}
- // TODO(eroman): This should really be a DataError, however for compatibility
- // with NSS it is an OperationError.
+ // TODO(eroman): This should be a DataError.
if (!RSA_check_key(rsa.get()))
return Status::OperationError();
@@ -149,6 +248,22 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
extractable, usages, key);
}
+// Converts a BIGNUM to a big endian byte array.
+std::vector<uint8_t> BIGNUMToVector(const BIGNUM* n) {
+ std::vector<uint8_t> v(BN_num_bytes(n));
+ BN_bn2bin(n, vector_as_array(&v));
+ return v;
+}
+
+// Synthesizes an import algorithm given a key algorithm, so that
+// deserialization can re-use the ImportKey*() methods.
+blink::WebCryptoAlgorithm SynthesizeImportAlgorithmForClone(
+ const blink::WebCryptoKeyAlgorithm& algorithm) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ algorithm.id(), new blink::WebCryptoRsaHashedImportParams(
+ algorithm.rsaHashedParams()->hash()));
+}
+
} // namespace
Status RsaHashedAlgorithm::GenerateKey(
@@ -168,12 +283,29 @@ Status RsaHashedAlgorithm::GenerateKey(
const blink::WebCryptoRsaHashedKeyGenParams* params =
algorithm.rsaHashedKeyGenParams();
+ unsigned int modulus_length_bits = params->modulusLengthBits();
+
+ // Limit the RSA key sizes to:
+ // * Multiple of 8 bits
+ // * 256 bits to 16K bits
+ //
+ // These correspond with limitations at the time there was an NSS WebCrypto
+ // implementation. However in practice the upper bound is also helpful
+ // because generating large RSA keys is very slow.
+ if (modulus_length_bits < 256 || modulus_length_bits > 16384 ||
+ (modulus_length_bits % 8) != 0) {
+ return Status::ErrorGenerateRsaUnsupportedModulus();
+ }
+
unsigned int public_exponent = 0;
- unsigned int modulus_length_bits = 0;
- status =
- GetRsaKeyGenParameters(params, &public_exponent, &modulus_length_bits);
- if (status.IsError())
- return status;
+ if (!BigIntegerToUint(params->publicExponent().data(),
+ params->publicExponent().size(), &public_exponent)) {
+ return Status::ErrorGenerateKeyPublicExponent();
+ }
+
+ // OpenSSL hangs when given bad public exponents. Use a whitelist.
+ if (public_exponent != 3 && public_exponent != 65537)
+ return Status::ErrorGenerateKeyPublicExponent();
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
@@ -301,9 +433,12 @@ Status RsaHashedAlgorithm::ImportKeyJwk(
return status;
// Once the key type is known, verify the usages.
- status = CheckKeyCreationUsages(
- jwk.is_private_key ? all_private_key_usages_ : all_public_key_usages_,
- usages, !jwk.is_private_key);
+ if (jwk.is_private_key) {
+ status = CheckPrivateKeyCreationUsages(all_private_key_usages_, usages);
+ } else {
+ status = CheckPublicKeyCreationUsages(all_public_key_usages_, usages);
+ }
+
if (status.IsError())
return status;
@@ -317,7 +452,10 @@ Status RsaHashedAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const {
if (key.type() != blink::WebCryptoKeyTypePrivate)
return Status::ErrorUnexpectedKeyType();
- *buffer = AsymKeyOpenSsl::Cast(key)->serialized_key_data();
+ // This relies on the fact that PKCS8 formatted data was already
+ // associated with the key during its creation (used by
+ // structured clone).
+ *buffer = GetSerializedKeyData(key);
return Status::Success();
}
@@ -325,7 +463,10 @@ Status RsaHashedAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const {
if (key.type() != blink::WebCryptoKeyTypePublic)
return Status::ErrorUnexpectedKeyType();
- *buffer = AsymKeyOpenSsl::Cast(key)->serialized_key_data();
+ // This relies on the fact that SPKI formatted data was already
+ // associated with the key during its creation (used by
+ // structured clone).
+ *buffer = GetSerializedKeyData(key);
return Status::Success();
}
@@ -333,7 +474,7 @@ Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- EVP_PKEY* pkey = AsymKeyOpenSsl::Cast(key)->key();
+ EVP_PKEY* pkey = GetEVP_PKEY(key);
crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey));
if (!rsa.get())
return Status::ErrorUnexpected();
@@ -344,36 +485,34 @@ Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key,
return Status::ErrorUnexpected();
switch (key.type()) {
- case blink::WebCryptoKeyTypePublic:
- WriteRsaPublicKeyJwk(CryptoData(BIGNUMToVector(rsa->n)),
- CryptoData(BIGNUMToVector(rsa->e)), jwk_algorithm,
- key.extractable(), key.usages(), buffer);
+ case blink::WebCryptoKeyTypePublic: {
+ JwkWriter writer(jwk_algorithm, key.extractable(), key.usages(), "RSA");
+ writer.SetBytes("n", CryptoData(BIGNUMToVector(rsa->n)));
+ writer.SetBytes("e", CryptoData(BIGNUMToVector(rsa->e)));
+ writer.ToJson(buffer);
return Status::Success();
- case blink::WebCryptoKeyTypePrivate:
- WriteRsaPrivateKeyJwk(CryptoData(BIGNUMToVector(rsa->n)),
- CryptoData(BIGNUMToVector(rsa->e)),
- CryptoData(BIGNUMToVector(rsa->d)),
- CryptoData(BIGNUMToVector(rsa->p)),
- CryptoData(BIGNUMToVector(rsa->q)),
- CryptoData(BIGNUMToVector(rsa->dmp1)),
- CryptoData(BIGNUMToVector(rsa->dmq1)),
- CryptoData(BIGNUMToVector(rsa->iqmp)),
- jwk_algorithm, key.extractable(), key.usages(),
- buffer);
+ }
+ case blink::WebCryptoKeyTypePrivate: {
+ JwkWriter writer(jwk_algorithm, key.extractable(), key.usages(), "RSA");
+ writer.SetBytes("n", CryptoData(BIGNUMToVector(rsa->n)));
+ writer.SetBytes("e", CryptoData(BIGNUMToVector(rsa->e)));
+ writer.SetBytes("d", CryptoData(BIGNUMToVector(rsa->d)));
+ // Although these are "optional" in the JWA, WebCrypto spec requires them
+ // to be emitted.
+ writer.SetBytes("p", CryptoData(BIGNUMToVector(rsa->p)));
+ writer.SetBytes("q", CryptoData(BIGNUMToVector(rsa->q)));
+ writer.SetBytes("dp", CryptoData(BIGNUMToVector(rsa->dmp1)));
+ writer.SetBytes("dq", CryptoData(BIGNUMToVector(rsa->dmq1)));
+ writer.SetBytes("qi", CryptoData(BIGNUMToVector(rsa->iqmp)));
+ writer.ToJson(buffer);
return Status::Success();
+ }
default:
return Status::ErrorUnexpected();
}
}
-Status RsaHashedAlgorithm::SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const {
- key_data->assign(AsymKeyOpenSsl::Cast(key)->serialized_key_data());
- return Status::Success();
-}
-
// TODO(eroman): Defer import to the crypto thread. http://crbug.com/430763
Status RsaHashedAlgorithm::DeserializeKeyForClone(
const blink::WebCryptoKeyAlgorithm& algorithm,
@@ -382,11 +521,12 @@ Status RsaHashedAlgorithm::DeserializeKeyForClone(
blink::WebCryptoKeyUsageMask usages,
const CryptoData& key_data,
blink::WebCryptoKey* key) const {
- blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
- algorithm.id(), algorithm.rsaHashedParams()->hash().id());
+ blink::WebCryptoAlgorithm import_algorithm =
+ SynthesizeImportAlgorithmForClone(algorithm);
Status status;
+ // The serialized data will be either SPKI or PKCS8 formatted.
switch (type) {
case blink::WebCryptoKeyTypePublic:
status =
diff --git a/chromium/components/webcrypto/openssl/rsa_hashed_algorithm_openssl.h b/chromium/components/webcrypto/algorithms/rsa.h
index 4c0d44b810d..c0c919b59b5 100644
--- a/chromium/components/webcrypto/openssl/rsa_hashed_algorithm_openssl.h
+++ b/chromium/components/webcrypto/algorithms/rsa.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_WEBCRYPTO_OPENSSL_RSA_HASHED_ALGORITHM_OPENSSL_H_
-#define COMPONENTS_WEBCRYPTO_OPENSSL_RSA_HASHED_ALGORITHM_OPENSSL_H_
+#ifndef COMPONENTS_WEBCRYPTO_ALGORITHMS_RSA_H_
+#define COMPONENTS_WEBCRYPTO_ALGORITHMS_RSA_H_
#include "components/webcrypto/algorithm_implementation.h"
@@ -69,10 +69,6 @@ class RsaHashedAlgorithm : public AlgorithmImplementation {
Status ExportKeyJwk(const blink::WebCryptoKey& key,
std::vector<uint8_t>* buffer) const override;
- Status SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const override;
-
Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
blink::WebCryptoKeyType type,
bool extractable,
@@ -87,4 +83,4 @@ class RsaHashedAlgorithm : public AlgorithmImplementation {
} // namespace webcrypto
-#endif // COMPONENTS_WEBCRYPTO_OPENSSL_RSA_HASHED_ALGORITHM_OPENSSL_H_
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_RSA_H_
diff --git a/chromium/components/webcrypto/openssl/rsa_oaep_openssl.cc b/chromium/components/webcrypto/algorithms/rsa_oaep.cc
index 1a43f725bc8..5a697095694 100644
--- a/chromium/components/webcrypto/openssl/rsa_oaep_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/rsa_oaep.cc
@@ -5,10 +5,10 @@
#include <openssl/evp.h>
#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/rsa.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/rsa_hashed_algorithm_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
@@ -41,9 +41,8 @@ Status CommonEncryptDecrypt(InitFunc init_func,
std::vector<uint8_t>* buffer) {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- EVP_PKEY* pkey = AsymKeyOpenSsl::Cast(key)->key();
- const EVP_MD* digest =
- GetDigest(key.algorithm().rsaHashedParams()->hash().id());
+ EVP_PKEY* pkey = GetEVP_PKEY(key);
+ const EVP_MD* digest = GetDigest(key.algorithm().rsaHashedParams()->hash());
if (!digest)
return Status::ErrorUnsupported();
@@ -139,8 +138,8 @@ class RsaOaepImplementation : public RsaHashedAlgorithm {
} // namespace
-AlgorithmImplementation* CreatePlatformRsaOaepImplementation() {
- return new RsaOaepImplementation;
+scoped_ptr<AlgorithmImplementation> CreateRsaOaepImplementation() {
+ return make_scoped_ptr(new RsaOaepImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/rsa_oaep_unittest.cc b/chromium/components/webcrypto/algorithms/rsa_oaep_unittest.cc
new file mode 100644
index 00000000000..32cd1353b4e
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/rsa_oaep_unittest.cc
@@ -0,0 +1,504 @@
+// 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 "base/logging.h"
+#include "base/stl_util.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/jwk.h"
+#include "components/webcrypto/status.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+// Creates an RSA-OAEP algorithm
+blink::WebCryptoAlgorithm CreateRsaOaepAlgorithm(
+ const std::vector<uint8_t>& label) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdRsaOaep,
+ new blink::WebCryptoRsaOaepParams(
+ !label.empty(), vector_as_array(&label),
+ static_cast<unsigned int>(label.size())));
+}
+
+scoped_ptr<base::DictionaryValue> CreatePublicKeyJwkDict() {
+ scoped_ptr<base::DictionaryValue> jwk(new base::DictionaryValue());
+ jwk->SetString("kty", "RSA");
+ jwk->SetString("n",
+ Base64EncodeUrlSafe(HexStringToBytes(kPublicKeyModulusHex)));
+ jwk->SetString("e",
+ Base64EncodeUrlSafe(HexStringToBytes(kPublicKeyExponentHex)));
+ return jwk.Pass();
+}
+
+class WebCryptoRsaOaepTest : public WebCryptoTestBase {};
+
+// Import a PKCS#8 private key that uses RSAPrivateKey with the
+// id-rsaEncryption OID.
+TEST_F(WebCryptoRsaOaepTest, ImportPkcs8WithRsaEncryption) {
+ blink::WebCryptoKey private_key;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatPkcs8,
+ CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageDecrypt, &private_key));
+}
+
+TEST_F(WebCryptoRsaOaepTest, ImportPublicJwkWithNoAlg) {
+ scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
+
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(
+ Status::Success(),
+ ImportKeyJwkFromDict(*jwk.get(), CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageEncrypt, &public_key));
+}
+
+TEST_F(WebCryptoRsaOaepTest, ImportPublicJwkWithMatchingAlg) {
+ scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
+ jwk->SetString("alg", "RSA-OAEP");
+
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(
+ Status::Success(),
+ ImportKeyJwkFromDict(*jwk.get(), CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageEncrypt, &public_key));
+}
+
+TEST_F(WebCryptoRsaOaepTest, ImportPublicJwkWithMismatchedAlgFails) {
+ scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
+ jwk->SetString("alg", "RSA-OAEP-512");
+
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(
+ Status::ErrorJwkAlgorithmInconsistent(),
+ ImportKeyJwkFromDict(*jwk.get(), CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageEncrypt, &public_key));
+}
+
+TEST_F(WebCryptoRsaOaepTest, ImportPublicJwkWithMismatchedTypeFails) {
+ scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
+ jwk->SetString("kty", "oct");
+ jwk->SetString("alg", "RSA-OAEP");
+
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(
+ Status::ErrorJwkUnexpectedKty("RSA"),
+ ImportKeyJwkFromDict(*jwk.get(), CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageEncrypt, &public_key));
+}
+
+TEST_F(WebCryptoRsaOaepTest, ExportPublicJwk) {
+ struct TestData {
+ blink::WebCryptoAlgorithmId hash_alg;
+ const char* expected_jwk_alg;
+ } kTestData[] = {{blink::WebCryptoAlgorithmIdSha1, "RSA-OAEP"},
+ {blink::WebCryptoAlgorithmIdSha256, "RSA-OAEP-256"},
+ {blink::WebCryptoAlgorithmIdSha384, "RSA-OAEP-384"},
+ {blink::WebCryptoAlgorithmIdSha512, "RSA-OAEP-512"}};
+ for (size_t i = 0; i < arraysize(kTestData); ++i) {
+ const TestData& test_data = kTestData[i];
+ SCOPED_TRACE(test_data.expected_jwk_alg);
+
+ scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
+ jwk->SetString("alg", test_data.expected_jwk_alg);
+
+ // Import the key in a known-good format
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(
+ *jwk.get(),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep, test_data.hash_alg),
+ true, blink::WebCryptoKeyUsageEncrypt, &public_key));
+
+ // Now export the key as JWK and verify its contents
+ std::vector<uint8_t> jwk_data;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &jwk_data));
+ EXPECT_TRUE(VerifyPublicJwk(jwk_data, test_data.expected_jwk_alg,
+ kPublicKeyModulusHex, kPublicKeyExponentHex,
+ blink::WebCryptoKeyUsageEncrypt));
+ }
+}
+
+TEST_F(WebCryptoRsaOaepTest, EncryptDecryptKnownAnswerTest) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("rsa_oaep.json", &tests));
+
+ for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ SCOPED_TRACE(test_index);
+
+ base::DictionaryValue* test = NULL;
+ ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+
+ blink::WebCryptoAlgorithm digest_algorithm =
+ GetDigestAlgorithm(test, "hash");
+ ASSERT_FALSE(digest_algorithm.isNull());
+ std::vector<uint8_t> public_key_der =
+ GetBytesFromHexString(test, "public_key");
+ std::vector<uint8_t> private_key_der =
+ GetBytesFromHexString(test, "private_key");
+ std::vector<uint8_t> ciphertext = GetBytesFromHexString(test, "ciphertext");
+ std::vector<uint8_t> plaintext = GetBytesFromHexString(test, "plaintext");
+ std::vector<uint8_t> label = GetBytesFromHexString(test, "label");
+
+ blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep, digest_algorithm.id());
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
+ public_key_der, private_key_der, import_algorithm, false,
+ blink::WebCryptoKeyUsageEncrypt, blink::WebCryptoKeyUsageDecrypt,
+ &public_key, &private_key));
+
+ blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
+ std::vector<uint8_t> decrypted_data;
+ ASSERT_EQ(Status::Success(),
+ Decrypt(op_algorithm, private_key, CryptoData(ciphertext),
+ &decrypted_data));
+ EXPECT_BYTES_EQ(plaintext, decrypted_data);
+ std::vector<uint8_t> encrypted_data;
+ ASSERT_EQ(Status::Success(),
+ Encrypt(op_algorithm, public_key, CryptoData(plaintext),
+ &encrypted_data));
+ std::vector<uint8_t> redecrypted_data;
+ ASSERT_EQ(Status::Success(),
+ Decrypt(op_algorithm, private_key, CryptoData(encrypted_data),
+ &redecrypted_data));
+ EXPECT_BYTES_EQ(plaintext, redecrypted_data);
+ }
+}
+
+TEST_F(WebCryptoRsaOaepTest, EncryptWithLargeMessageFails) {
+ const blink::WebCryptoAlgorithmId kHash = blink::WebCryptoAlgorithmIdSha1;
+ const size_t kHashSize = 20;
+
+ scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
+
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(
+ *jwk.get(), CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep, kHash),
+ true, blink::WebCryptoKeyUsageEncrypt, &public_key));
+
+ // The maximum size of an encrypted message is:
+ // modulus length
+ // - 1 (leading octet)
+ // - hash size (maskedSeed)
+ // - hash size (lHash portion of maskedDB)
+ // - 1 (at least one octet for the padding string)
+ size_t kMaxMessageSize = (kModulusLengthBits / 8) - 2 - (2 * kHashSize);
+
+ // The label has no influence on the maximum message size. For simplicity,
+ // use the empty string.
+ std::vector<uint8_t> label;
+ blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
+
+ // Test that a message just before the boundary succeeds.
+ std::string large_message;
+ large_message.resize(kMaxMessageSize - 1, 'A');
+
+ std::vector<uint8_t> ciphertext;
+ ASSERT_EQ(Status::Success(), Encrypt(op_algorithm, public_key,
+ CryptoData(large_message), &ciphertext));
+
+ // Test that a message at the boundary succeeds.
+ large_message.resize(kMaxMessageSize, 'A');
+ ciphertext.clear();
+
+ ASSERT_EQ(Status::Success(), Encrypt(op_algorithm, public_key,
+ CryptoData(large_message), &ciphertext));
+
+ // Test that a message greater than the largest size fails.
+ large_message.resize(kMaxMessageSize + 1, 'A');
+ ciphertext.clear();
+
+ ASSERT_EQ(Status::OperationError(),
+ Encrypt(op_algorithm, public_key, CryptoData(large_message),
+ &ciphertext));
+}
+
+// Ensures that if the selected hash algorithm for the RSA-OAEP message is too
+// large, then it is rejected, independent of the actual message to be
+// encrypted.
+// For example, a 1024-bit RSA key is too small to accomodate a message that
+// uses OAEP with SHA-512, since it requires 1040 bits to encode
+// (2 * hash size + 2 padding bytes).
+TEST_F(WebCryptoRsaOaepTest, EncryptWithLargeDigestFails) {
+ const blink::WebCryptoAlgorithmId kHash = blink::WebCryptoAlgorithmIdSha512;
+
+ scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
+
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(
+ *jwk.get(), CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep, kHash),
+ true, blink::WebCryptoKeyUsageEncrypt, &public_key));
+
+ // The label has no influence on the maximum message size. For simplicity,
+ // use the empty string.
+ std::vector<uint8_t> label;
+ blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
+
+ std::string small_message("A");
+ std::vector<uint8_t> ciphertext;
+ // This is an operation error, as the internal consistency checking of the
+ // algorithm parameters is up to the implementation.
+ ASSERT_EQ(Status::OperationError(),
+ Encrypt(op_algorithm, public_key, CryptoData(small_message),
+ &ciphertext));
+}
+
+TEST_F(WebCryptoRsaOaepTest, DecryptWithLargeMessageFails) {
+ blink::WebCryptoKey private_key;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatPkcs8,
+ CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageDecrypt, &private_key));
+
+ // The label has no influence on the maximum message size. For simplicity,
+ // use the empty string.
+ std::vector<uint8_t> label;
+ blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
+
+ std::string large_dummy_message(kModulusLengthBits / 8, 'A');
+ std::vector<uint8_t> plaintext;
+
+ ASSERT_EQ(Status::OperationError(),
+ Decrypt(op_algorithm, private_key, CryptoData(large_dummy_message),
+ &plaintext));
+}
+
+TEST_F(WebCryptoRsaOaepTest, WrapUnwrapRawKey) {
+ blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep, blink::WebCryptoAlgorithmIdSha1);
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
+ HexStringToBytes(kPublicKeySpkiDerHex),
+ HexStringToBytes(kPrivateKeyPkcs8DerHex), import_algorithm, false,
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageWrapKey,
+ blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageUnwrapKey,
+ &public_key, &private_key));
+
+ std::vector<uint8_t> label;
+ blink::WebCryptoAlgorithm wrapping_algorithm = CreateRsaOaepAlgorithm(label);
+
+ const std::string key_hex = "000102030405060708090A0B0C0D0E0F";
+ const blink::WebCryptoAlgorithm key_algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
+
+ blink::WebCryptoKey key =
+ ImportSecretKeyFromRaw(HexStringToBytes(key_hex), key_algorithm,
+ blink::WebCryptoKeyUsageEncrypt);
+ ASSERT_FALSE(key.isNull());
+
+ std::vector<uint8_t> wrapped_key;
+ ASSERT_EQ(Status::Success(),
+ WrapKey(blink::WebCryptoKeyFormatRaw, key, public_key,
+ wrapping_algorithm, &wrapped_key));
+
+ // Verify that |wrapped_key| can be decrypted and yields the key data.
+ // Because |private_key| supports both decrypt and unwrap, this is valid.
+ std::vector<uint8_t> decrypted_key;
+ ASSERT_EQ(Status::Success(),
+ Decrypt(wrapping_algorithm, private_key, CryptoData(wrapped_key),
+ &decrypted_key));
+ EXPECT_BYTES_EQ_HEX(key_hex, decrypted_key);
+
+ // Now attempt to unwrap the key, which should also decrypt the data.
+ blink::WebCryptoKey unwrapped_key;
+ ASSERT_EQ(Status::Success(),
+ UnwrapKey(blink::WebCryptoKeyFormatRaw, CryptoData(wrapped_key),
+ private_key, wrapping_algorithm, key_algorithm, true,
+ blink::WebCryptoKeyUsageEncrypt, &unwrapped_key));
+ ASSERT_FALSE(unwrapped_key.isNull());
+
+ std::vector<uint8_t> raw_key;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key));
+ EXPECT_BYTES_EQ_HEX(key_hex, raw_key);
+}
+
+TEST_F(WebCryptoRsaOaepTest, WrapUnwrapJwkSymKey) {
+ // The public and private portions of a 2048-bit RSA key with the
+ // id-rsaEncryption OID
+ const char kPublicKey2048SpkiDerHex[] =
+ "30820122300d06092a864886f70d01010105000382010f003082010a0282010100c5d8ce"
+ "137a38168c8ab70229cfa5accc640567159750a312ce2e7d54b6e2fdd59b300c6a6c9764"
+ "f8de6f00519cdb90111453d273a967462786480621f9e7cee5b73d63358448e7183a3a68"
+ "e991186359f26aa88fbca5f53e673e502e4c5a2ba5068aeba60c9d0c44d872458d1b1e2f"
+ "7f339f986076d516e93dc750f0b7680b6f5f02bc0d5590495be04c4ae59d34ba17bc5d08"
+ "a93c75cfda2828f4a55b153af912038438276cb4a14f8116ca94db0ea9893652d02fc606"
+ "36f19975e3d79a4d8ea8bfed6f8e0a24b63d243b08ea70a086ad56dd6341d733711c89ca"
+ "749d4a80b3e6ecd2f8e53731eadeac2ea77788ee55d7b4b47c0f2523fbd61b557c16615d"
+ "5d0203010001";
+ const char kPrivateKey2048Pkcs8DerHex[] =
+ "308204bd020100300d06092a864886f70d0101010500048204a7308204a3020100028201"
+ "0100c5d8ce137a38168c8ab70229cfa5accc640567159750a312ce2e7d54b6e2fdd59b30"
+ "0c6a6c9764f8de6f00519cdb90111453d273a967462786480621f9e7cee5b73d63358448"
+ "e7183a3a68e991186359f26aa88fbca5f53e673e502e4c5a2ba5068aeba60c9d0c44d872"
+ "458d1b1e2f7f339f986076d516e93dc750f0b7680b6f5f02bc0d5590495be04c4ae59d34"
+ "ba17bc5d08a93c75cfda2828f4a55b153af912038438276cb4a14f8116ca94db0ea98936"
+ "52d02fc60636f19975e3d79a4d8ea8bfed6f8e0a24b63d243b08ea70a086ad56dd6341d7"
+ "33711c89ca749d4a80b3e6ecd2f8e53731eadeac2ea77788ee55d7b4b47c0f2523fbd61b"
+ "557c16615d5d02030100010282010074b70feb41a0b0fcbc207670400556c9450042ede3"
+ "d4383fb1ce8f3558a6d4641d26dd4c333fa4db842d2b9cf9d2354d3e16ad027a9f682d8c"
+ "f4145a1ad97b9edcd8a41c402bd9d8db10f62f43df854cdccbbb2100834f083f53ed6d42"
+ "b1b729a59072b004a4e945fc027db15e9c121d1251464d320d4774d5732df6b3dbf751f4"
+ "9b19c9db201e19989c883bbaad5333db47f64f6f7a95b8d4936b10d945aa3f794cfaab62"
+ "e7d47686129358914f3b8085f03698a650ab5b8c7e45813f2b0515ec05b6e5195b6a7c2a"
+ "0d36969745f431ded4fd059f6aa361a4649541016d356297362b778e90f077d48815b339"
+ "ec6f43aba345df93e67fcb6c2cb5b4544e9be902818100e9c90abe5f9f32468c5b6d630c"
+ "54a4d7d75e29a72cf792f21e242aac78fd7995c42dfd4ae871d2619ff7096cb05baa78e3"
+ "23ecab338401a8059adf7a0d8be3b21edc9a9c82c5605634a2ec81ec053271721351868a"
+ "4c2e50c689d7cef94e31ff23658af5843366e2b289c5bf81d72756a7b93487dd8770d69c"
+ "1f4e089d6d89f302818100d8a58a727c4e209132afd9933b98c89aca862a01cc0be74133"
+ "bee517909e5c379e526895ac4af11780c1fe91194c777c9670b6423f0f5a32fd7691a622"
+ "113eef4bed2ef863363a335fd55b0e75088c582437237d7f3ed3f0a643950237bc6e6277"
+ "ccd0d0a1b4170aa1047aa7ffa7c8c54be10e8c7327ae2e0885663963817f6f02818100e5"
+ "aed9ba4d71b7502e6748a1ce247ecb7bd10c352d6d9256031cdf3c11a65e44b0b7ca2945"
+ "134671195af84c6b3bb3d10ebf65ae916f38bd5dbc59a0ad1c69b8beaf57cb3a8335f19b"
+ "c7117b576987b48331cd9fd3d1a293436b7bb5e1a35c6560de4b5688ea834367cb0997eb"
+ "b578f59ed4cb724c47dba94d3b484c1876dcd70281807f15bc7d2406007cac2b138a96af"
+ "2d1e00276b84da593132c253fcb73212732dfd25824c2a615bc3d9b7f2c8d2fa542d3562"
+ "b0c7738e61eeff580a6056239fb367ea9e5efe73d4f846033602e90c36a78db6fa8ea792"
+ "0769675ec58e237bd994d189c8045a96f5dd3a4f12547257ce224e3c9af830a4da3c0eab"
+ "9227a0035ae9028180067caea877e0b23090fc689322b71fbcce63d6596e66ab5fcdbaa0"
+ "0d49e93aba8effb4518c2da637f209028401a68f344865b4956b032c69acde51d29177ca"
+ "3db99fdbf5e74848ed4fa7bdfc2ebb60e2aaa5354770a763e1399ab7a2099762d525fea0"
+ "37f3e1972c45a477e66db95c9609bb27f862700ef93379930786cf751b";
+ blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaOaep, blink::WebCryptoAlgorithmIdSha1);
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
+ HexStringToBytes(kPublicKey2048SpkiDerHex),
+ HexStringToBytes(kPrivateKey2048Pkcs8DerHex), import_algorithm, false,
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageWrapKey,
+ blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageUnwrapKey,
+ &public_key, &private_key));
+
+ std::vector<uint8_t> label;
+ blink::WebCryptoAlgorithm wrapping_algorithm = CreateRsaOaepAlgorithm(label);
+
+ const std::string key_hex = "000102030405060708090a0b0c0d0e0f";
+ const blink::WebCryptoAlgorithm key_algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
+
+ blink::WebCryptoKey key =
+ ImportSecretKeyFromRaw(HexStringToBytes(key_hex), key_algorithm,
+ blink::WebCryptoKeyUsageEncrypt);
+ ASSERT_FALSE(key.isNull());
+
+ std::vector<uint8_t> wrapped_key;
+ ASSERT_EQ(Status::Success(),
+ WrapKey(blink::WebCryptoKeyFormatJwk, key, public_key,
+ wrapping_algorithm, &wrapped_key));
+
+ // Verify that |wrapped_key| can be decrypted and yields a valid JWK object.
+ // Because |private_key| supports both decrypt and unwrap, this is valid.
+ std::vector<uint8_t> decrypted_jwk;
+ ASSERT_EQ(Status::Success(),
+ Decrypt(wrapping_algorithm, private_key, CryptoData(wrapped_key),
+ &decrypted_jwk));
+ EXPECT_TRUE(VerifySecretJwk(decrypted_jwk, "A128CBC", key_hex,
+ blink::WebCryptoKeyUsageEncrypt));
+
+ // Now attempt to unwrap the key, which should also decrypt the data.
+ blink::WebCryptoKey unwrapped_key;
+ ASSERT_EQ(Status::Success(),
+ UnwrapKey(blink::WebCryptoKeyFormatJwk, CryptoData(wrapped_key),
+ private_key, wrapping_algorithm, key_algorithm, true,
+ blink::WebCryptoKeyUsageEncrypt, &unwrapped_key));
+ ASSERT_FALSE(unwrapped_key.isNull());
+
+ std::vector<uint8_t> raw_key;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key));
+ EXPECT_BYTES_EQ_HEX(key_hex, raw_key);
+}
+
+TEST_F(WebCryptoRsaOaepTest, ImportExportJwkRsaPublicKey) {
+ struct TestCase {
+ const blink::WebCryptoAlgorithmId hash;
+ const blink::WebCryptoKeyUsageMask usage;
+ const char* const jwk_alg;
+ };
+ const TestCase kTests[] = {{blink::WebCryptoAlgorithmIdSha1,
+ blink::WebCryptoKeyUsageEncrypt,
+ "RSA-OAEP"},
+ {blink::WebCryptoAlgorithmIdSha256,
+ blink::WebCryptoKeyUsageEncrypt,
+ "RSA-OAEP-256"},
+ {blink::WebCryptoAlgorithmIdSha384,
+ blink::WebCryptoKeyUsageEncrypt,
+ "RSA-OAEP-384"},
+ {blink::WebCryptoAlgorithmIdSha512,
+ blink::WebCryptoKeyUsageEncrypt,
+ "RSA-OAEP-512"}};
+
+ for (size_t test_index = 0; test_index < arraysize(kTests); ++test_index) {
+ SCOPED_TRACE(test_index);
+ const TestCase& test = kTests[test_index];
+
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaOaep,
+ test.hash);
+
+ // Import the spki to create a public key
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatSpki,
+ CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
+ import_algorithm, true, test.usage, &public_key));
+
+ // Export the public key as JWK and verify its contents
+ std::vector<uint8_t> jwk;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &jwk));
+ EXPECT_TRUE(VerifyPublicJwk(jwk, test.jwk_alg, kPublicKeyModulusHex,
+ kPublicKeyExponentHex, test.usage));
+
+ // Import the JWK back in to create a new key
+ blink::WebCryptoKey public_key2;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(jwk),
+ import_algorithm, true, test.usage, &public_key2));
+ ASSERT_TRUE(public_key2.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key2.type());
+ EXPECT_TRUE(public_key2.extractable());
+ EXPECT_EQ(import_algorithm.id(), public_key2.algorithm().id());
+
+ // TODO(eroman): Export the SPKI and verify matches.
+ }
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/rsa_pss_openssl.cc b/chromium/components/webcrypto/algorithms/rsa_pss.cc
index 68c288f6366..14166bd9a13 100644
--- a/chromium/components/webcrypto/openssl/rsa_pss_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/rsa_pss.cc
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/webcrypto/openssl/rsa_hashed_algorithm_openssl.h"
-#include "components/webcrypto/openssl/rsa_sign_openssl.h"
+#include "components/webcrypto/algorithms/rsa.h"
+#include "components/webcrypto/algorithms/rsa_sign.h"
#include "components/webcrypto/status.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -53,8 +53,8 @@ class RsaPssImplementation : public RsaHashedAlgorithm {
} // namespace
-AlgorithmImplementation* CreatePlatformRsaPssImplementation() {
- return new RsaPssImplementation;
+scoped_ptr<AlgorithmImplementation> CreateRsaPssImplementation() {
+ return make_scoped_ptr(new RsaPssImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/rsa_pss_unittest.cc b/chromium/components/webcrypto/algorithms/rsa_pss_unittest.cc
new file mode 100644
index 00000000000..e8b2bfd5b55
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/rsa_pss_unittest.cc
@@ -0,0 +1,230 @@
+// 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 "base/logging.h"
+#include "base/stl_util.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/jwk.h"
+#include "components/webcrypto/status.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+blink::WebCryptoAlgorithm CreateRsaPssAlgorithm(
+ unsigned int salt_length_bytes) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdRsaPss,
+ new blink::WebCryptoRsaPssParams(salt_length_bytes));
+}
+
+class WebCryptoRsaPssTest : public WebCryptoTestBase {};
+
+// Test that no two RSA-PSS signatures are identical, when using a non-zero
+// lengthed salt.
+TEST_F(WebCryptoRsaPssTest, SignIsRandom) {
+ // Import public/private key pair.
+ blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+ blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+
+ ImportRsaKeyPair(
+ HexStringToBytes(kPublicKeySpkiDerHex),
+ HexStringToBytes(kPrivateKeyPkcs8DerHex),
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaPss,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageVerify, blink::WebCryptoKeyUsageSign,
+ &public_key, &private_key);
+
+ // Use a 20-byte length salt.
+ blink::WebCryptoAlgorithm params = CreateRsaPssAlgorithm(20);
+
+ // Some random message to sign.
+ std::vector<uint8_t> message = HexStringToBytes(kPublicKeySpkiDerHex);
+
+ // Sign twice.
+ std::vector<uint8_t> signature1;
+ std::vector<uint8_t> signature2;
+
+ ASSERT_EQ(Status::Success(),
+ Sign(params, private_key, CryptoData(message), &signature1));
+ ASSERT_EQ(Status::Success(),
+ Sign(params, private_key, CryptoData(message), &signature2));
+
+ // The signatures will be different because of the salt.
+ EXPECT_NE(CryptoData(signature1), CryptoData(signature2));
+
+ // However both signatures should work when verifying.
+ bool is_match = false;
+
+ ASSERT_EQ(Status::Success(),
+ Verify(params, public_key, CryptoData(signature1),
+ CryptoData(message), &is_match));
+ EXPECT_TRUE(is_match);
+
+ ASSERT_EQ(Status::Success(),
+ Verify(params, public_key, CryptoData(signature2),
+ CryptoData(message), &is_match));
+ EXPECT_TRUE(is_match);
+
+ // Corrupt the signature and verification must fail.
+ ASSERT_EQ(Status::Success(),
+ Verify(params, public_key, CryptoData(Corrupted(signature2)),
+ CryptoData(message), &is_match));
+ EXPECT_FALSE(is_match);
+}
+
+// Try signing and verifying when the salt length is 0. The signature in this
+// case is not random.
+TEST_F(WebCryptoRsaPssTest, SignVerifyNoSalt) {
+ // Import public/private key pair.
+ blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+ blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+
+ ImportRsaKeyPair(
+ HexStringToBytes(kPublicKeySpkiDerHex),
+ HexStringToBytes(kPrivateKeyPkcs8DerHex),
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaPss,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageVerify, blink::WebCryptoKeyUsageSign,
+ &public_key, &private_key);
+
+ // Zero-length salt.
+ blink::WebCryptoAlgorithm params = CreateRsaPssAlgorithm(0);
+
+ // Some random message to sign.
+ std::vector<uint8_t> message = HexStringToBytes(kPublicKeySpkiDerHex);
+
+ // Sign twice.
+ std::vector<uint8_t> signature1;
+ std::vector<uint8_t> signature2;
+
+ ASSERT_EQ(Status::Success(),
+ Sign(params, private_key, CryptoData(message), &signature1));
+ ASSERT_EQ(Status::Success(),
+ Sign(params, private_key, CryptoData(message), &signature2));
+
+ // The signatures will be the same this time.
+ EXPECT_EQ(CryptoData(signature1), CryptoData(signature2));
+
+ // Make sure that verification works.
+ bool is_match = false;
+ ASSERT_EQ(Status::Success(),
+ Verify(params, public_key, CryptoData(signature1),
+ CryptoData(message), &is_match));
+ EXPECT_TRUE(is_match);
+
+ // Corrupt the signature and verification must fail.
+ ASSERT_EQ(Status::Success(),
+ Verify(params, public_key, CryptoData(Corrupted(signature2)),
+ CryptoData(message), &is_match));
+ EXPECT_FALSE(is_match);
+}
+
+TEST_F(WebCryptoRsaPssTest, SignEmptyMessage) {
+ // Import public/private key pair.
+ blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+ blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+
+ ImportRsaKeyPair(
+ HexStringToBytes(kPublicKeySpkiDerHex),
+ HexStringToBytes(kPrivateKeyPkcs8DerHex),
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaPss,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageVerify, blink::WebCryptoKeyUsageSign,
+ &public_key, &private_key);
+
+ blink::WebCryptoAlgorithm params = CreateRsaPssAlgorithm(20);
+ std::vector<uint8_t> message; // Empty message.
+ std::vector<uint8_t> signature;
+
+ ASSERT_EQ(Status::Success(),
+ Sign(params, private_key, CryptoData(message), &signature));
+
+ // Make sure that verification works.
+ bool is_match = false;
+ ASSERT_EQ(Status::Success(), Verify(params, public_key, CryptoData(signature),
+ CryptoData(message), &is_match));
+ EXPECT_TRUE(is_match);
+
+ // Corrupt the signature and verification must fail.
+ ASSERT_EQ(Status::Success(),
+ Verify(params, public_key, CryptoData(Corrupted(signature)),
+ CryptoData(message), &is_match));
+ EXPECT_FALSE(is_match);
+}
+
+// Iterate through known answers and test verification.
+// * Verify over original message should succeed
+// * Verify over corrupted message should fail
+// * Verification with corrupted signature should fail
+TEST_F(WebCryptoRsaPssTest, VerifyKnownAnswer) {
+ scoped_ptr<base::DictionaryValue> test_data;
+ ASSERT_TRUE(ReadJsonTestFileToDictionary("rsa_pss.json", &test_data));
+
+ const base::DictionaryValue* keys_dict = NULL;
+ ASSERT_TRUE(test_data->GetDictionary("keys", &keys_dict));
+
+ const base::ListValue* tests = NULL;
+ ASSERT_TRUE(test_data->GetList("tests", &tests));
+
+ 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));
+
+ blink::WebCryptoAlgorithm hash = GetDigestAlgorithm(test, "hash");
+
+ std::string key_name;
+ ASSERT_TRUE(test->GetString("key", &key_name));
+
+ // Import the public key.
+ blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+ std::vector<uint8_t> spki_bytes =
+ GetBytesFromHexString(keys_dict, key_name);
+
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatSpki, CryptoData(spki_bytes),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaPss, hash.id()),
+ true, blink::WebCryptoKeyUsageVerify, &public_key));
+
+ int saltLength;
+ ASSERT_TRUE(test->GetInteger("saltLength", &saltLength));
+
+ std::vector<uint8_t> message = GetBytesFromHexString(test, "message");
+ std::vector<uint8_t> signature = GetBytesFromHexString(test, "signature");
+
+ // Test that verification returns true when it should.
+ bool is_match = false;
+ ASSERT_EQ(Status::Success(),
+ Verify(CreateRsaPssAlgorithm(saltLength), public_key,
+ CryptoData(signature), CryptoData(message), &is_match));
+ EXPECT_TRUE(is_match);
+
+ // Corrupt the message and make sure that verification fails.
+ ASSERT_EQ(Status::Success(),
+ Verify(CreateRsaPssAlgorithm(saltLength), public_key,
+ CryptoData(signature), CryptoData(Corrupted(message)),
+ &is_match));
+ EXPECT_FALSE(is_match);
+
+ // Corrupt the signature and make sure that verification fails.
+ ASSERT_EQ(Status::Success(),
+ Verify(CreateRsaPssAlgorithm(saltLength), public_key,
+ CryptoData(Corrupted(signature)), CryptoData(message),
+ &is_match));
+ EXPECT_FALSE(is_match);
+ }
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/rsa_sign_openssl.cc b/chromium/components/webcrypto/algorithms/rsa_sign.cc
index 41d14e87d23..5c038b543d8 100644
--- a/chromium/components/webcrypto/openssl/rsa_sign_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/rsa_sign.cc
@@ -4,10 +4,10 @@
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/rsa_sign.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/openssl/key_openssl.h"
-#include "components/webcrypto/openssl/rsa_sign_openssl.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
@@ -22,9 +22,9 @@ namespace {
Status GetPKeyAndDigest(const blink::WebCryptoKey& key,
EVP_PKEY** pkey,
const EVP_MD** digest) {
- *pkey = AsymKeyOpenSsl::Cast(key)->key();
+ *pkey = GetEVP_PKEY(key);
- *digest = GetDigest(key.algorithm().rsaHashedParams()->hash().id());
+ *digest = GetDigest(key.algorithm().rsaHashedParams()->hash());
if (!*digest)
return Status::ErrorUnsupported();
diff --git a/chromium/components/webcrypto/openssl/rsa_sign_openssl.h b/chromium/components/webcrypto/algorithms/rsa_sign.h
index 9aacfb18600..2e3f09200cf 100644
--- a/chromium/components/webcrypto/openssl/rsa_sign_openssl.h
+++ b/chromium/components/webcrypto/algorithms/rsa_sign.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_WEBCRYPTO_OPENSSL_RSA_SIGN_OPENSSL_H_
-#define COMPONENTS_WEBCRYPTO_OPENSSL_RSA_SIGN_OPENSSL_H_
+#ifndef COMPONENTS_WEBCRYPTO_ALGORITHMS_RSA_SIGN_H_
+#define COMPONENTS_WEBCRYPTO_ALGORITHMS_RSA_SIGN_H_
#include <stdint.h>
@@ -37,4 +37,4 @@ Status RsaVerify(const blink::WebCryptoKey& key,
} // namespace webcrypto
-#endif // COMPONENTS_WEBCRYPTO_OPENSSL_RSA_SIGN_OPENSSL_H_
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_RSA_SIGN_H_
diff --git a/chromium/components/webcrypto/openssl/rsa_ssa_openssl.cc b/chromium/components/webcrypto/algorithms/rsa_ssa.cc
index 257a6a9d97e..54eefbb8a52 100644
--- a/chromium/components/webcrypto/openssl/rsa_ssa_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/rsa_ssa.cc
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/webcrypto/openssl/rsa_hashed_algorithm_openssl.h"
-#include "components/webcrypto/openssl/rsa_sign_openssl.h"
+#include "components/webcrypto/algorithms/rsa.h"
+#include "components/webcrypto/algorithms/rsa_sign.h"
#include "components/webcrypto/status.h"
namespace webcrypto {
@@ -50,8 +50,8 @@ class RsaSsaImplementation : public RsaHashedAlgorithm {
} // namespace
-AlgorithmImplementation* CreatePlatformRsaSsaImplementation() {
- return new RsaSsaImplementation;
+scoped_ptr<AlgorithmImplementation> CreateRsaSsaImplementation() {
+ return make_scoped_ptr(new RsaSsaImplementation);
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/rsa_ssa_unittest.cc b/chromium/components/webcrypto/algorithms/rsa_ssa_unittest.cc
new file mode 100644
index 00000000000..31cc967b386
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/rsa_ssa_unittest.cc
@@ -0,0 +1,1020 @@
+// 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 "base/logging.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+// Helper for ImportJwkRsaFailures. Restores the JWK JSON
+// dictionary to a good state
+void RestoreJwkRsaDictionary(base::DictionaryValue* dict) {
+ dict->Clear();
+ dict->SetString("kty", "RSA");
+ dict->SetString("alg", "RS256");
+ dict->SetString("use", "sig");
+ dict->SetBoolean("ext", false);
+ dict->SetString(
+ "n",
+ "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk"
+ "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm"
+ "e7PUJHYW1PW6ENTP0ibeiNOfFvs");
+ dict->SetString("e", "AQAB");
+}
+
+class WebCryptoRsaSsaTest : public WebCryptoTestBase {};
+
+TEST_F(WebCryptoRsaSsaTest, ImportExportSpki) {
+ // Passing case: Import a valid RSA key in SPKI format.
+ blink::WebCryptoKey key;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatSpki,
+ CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, blink::WebCryptoKeyUsageVerify, &key));
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type());
+ EXPECT_TRUE(key.extractable());
+ EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages());
+ EXPECT_EQ(kModulusLengthBits,
+ key.algorithm().rsaHashedParams()->modulusLengthBits());
+ EXPECT_BYTES_EQ_HEX(
+ "010001",
+ CryptoData(key.algorithm().rsaHashedParams()->publicExponent()));
+
+ // Failing case: Import RSA key but provide an inconsistent input algorithm.
+ EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(),
+ ImportKey(blink::WebCryptoKeyFormatSpki,
+ CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true,
+ blink::WebCryptoKeyUsageEncrypt, &key));
+
+ // Passing case: Export a previously imported RSA public key in SPKI format
+ // and compare to original data.
+ std::vector<uint8_t> output;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatSpki, key, &output));
+ EXPECT_BYTES_EQ_HEX(kPublicKeySpkiDerHex, output);
+
+ // Failing case: Try to export a previously imported RSA public key in raw
+ // format (not allowed for a public key).
+ EXPECT_EQ(Status::ErrorUnsupportedExportKeyFormat(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &output));
+
+ // Failing case: Try to export a non-extractable key
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatSpki,
+ CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ false, blink::WebCryptoKeyUsageVerify, &key));
+ EXPECT_TRUE(key.handle());
+ EXPECT_FALSE(key.extractable());
+ EXPECT_EQ(Status::ErrorKeyNotExtractable(),
+ ExportKey(blink::WebCryptoKeyFormatSpki, key, &output));
+
+ // TODO(eroman): Failing test: Import a SPKI with an unrecognized hash OID
+ // TODO(eroman): Failing test: Import a SPKI with invalid algorithm params
+ // TODO(eroman): Failing test: Import a SPKI with inconsistent parameters
+ // (e.g. SHA-1 in OID, SHA-256 in params)
+ // TODO(eroman): Failing test: Import a SPKI for RSA-SSA, but with params
+ // as OAEP/PSS
+}
+
+TEST_F(WebCryptoRsaSsaTest, ImportExportPkcs8) {
+ // Passing case: Import a valid RSA key in PKCS#8 format.
+ blink::WebCryptoKey key;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatPkcs8,
+ CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageSign, &key));
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypePrivate, key.type());
+ EXPECT_TRUE(key.extractable());
+ EXPECT_EQ(blink::WebCryptoKeyUsageSign, key.usages());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha1,
+ key.algorithm().rsaHashedParams()->hash().id());
+ EXPECT_EQ(kModulusLengthBits,
+ key.algorithm().rsaHashedParams()->modulusLengthBits());
+ EXPECT_BYTES_EQ_HEX(
+ "010001",
+ CryptoData(key.algorithm().rsaHashedParams()->publicExponent()));
+
+ std::vector<uint8_t> exported_key;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatPkcs8, key, &exported_key));
+ EXPECT_BYTES_EQ_HEX(kPrivateKeyPkcs8DerHex, exported_key);
+
+ // Failing case: Import RSA key but provide an inconsistent input algorithm
+ // and usage. Several issues here:
+ // * AES-CBC doesn't support PKCS8 key format
+ // * AES-CBC doesn't support "sign" usage
+ EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(),
+ ImportKey(blink::WebCryptoKeyFormatPkcs8,
+ CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true,
+ blink::WebCryptoKeyUsageSign, &key));
+}
+
+// Tests JWK import and export by doing a roundtrip key conversion and ensuring
+// it was lossless:
+//
+// PKCS8 --> JWK --> PKCS8
+TEST_F(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkToPkcs8RoundTrip) {
+ blink::WebCryptoKey key;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatPkcs8,
+ CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageSign, &key));
+
+ std::vector<uint8_t> exported_key_jwk;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, key, &exported_key_jwk));
+
+ // All of the optional parameters (p, q, dp, dq, qi) should be present in the
+ // output.
+ const char* expected_jwk =
+ "{\"alg\":\"RS1\",\"d\":\"M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-"
+ "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ"
+ "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU\",\"dp\":"
+ "\"KPoTk4ZVvh-"
+ "KFZy6ylpy6hkMMAieGc0nSlVvNsT24Z9VSzTAd3kEJ7vdjdPt4kSDKPOF2Bsw6OQ7L_-"
+ "gJ4YZeQ\",\"dq\":\"Gos485j6cSBJiY1_t57gp3ZoeRKZzfoJ78DlB6yyHtdDAe9b_Ui-"
+ "RV6utuFnglWCdYCo5OjhQVHRUQqCo_LnKQ\",\"e\":\"AQAB\",\"ext\":true,\"key_"
+ "ops\":[\"sign\"],\"kty\":\"RSA\",\"n\":"
+ "\"pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_"
+ "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_"
+ "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc\",\"p\":\"5-"
+ "iUJyCod1Fyc6NWBT6iobwMlKpy1VxuhilrLfyWeUjApyy8zKfqyzVwbgmh31WhU1vZs8w0Fg"
+ "s7bc0-2o5kQw\",\"q\":\"tp3KHPfU1-yB51uQ_MqHSrzeEj_"
+ "ScAGAqpBHm25I3o1n7ST58Z2FuidYdPVCzSDccj5pYzZKH5QlRSsmmmeZ_Q\",\"qi\":"
+ "\"JxVqukEm0kqB86Uoy_sn9WiG-"
+ "ECp9uhuF6RLlP6TGVhLjiL93h5aLjvYqluo2FhBlOshkKz4MrhH8To9JKefTQ\"}";
+
+ ASSERT_EQ(CryptoData(std::string(expected_jwk)),
+ CryptoData(exported_key_jwk));
+
+ ASSERT_EQ(
+ Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(exported_key_jwk),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageSign, &key));
+
+ std::vector<uint8_t> exported_key_pkcs8;
+ ASSERT_EQ(Status::Success(), ExportKey(blink::WebCryptoKeyFormatPkcs8, key,
+ &exported_key_pkcs8));
+
+ ASSERT_EQ(CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
+ CryptoData(exported_key_pkcs8));
+}
+
+// Tests importing multiple RSA private keys from JWK, and then exporting to
+// PKCS8.
+//
+// This is a regression test for http://crbug.com/378315, for which importing
+// a sequence of keys from JWK could yield the wrong key. The first key would
+// be imported correctly, however every key after that would actually import
+// the first key.
+TEST_F(WebCryptoRsaSsaTest, ImportMultipleRSAPrivateKeysJwk) {
+ scoped_ptr<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) {
+ SCOPED_TRACE(key_index);
+
+ base::DictionaryValue* key_values;
+ ASSERT_TRUE(key_list->GetDictionary(key_index, &key_values));
+
+ // Get the JWK representation of the key.
+ base::DictionaryValue* key_jwk;
+ ASSERT_TRUE(key_values->GetDictionary("jwk", &key_jwk));
+
+ // Get the PKCS8 representation of the key.
+ std::string pkcs8_hex_string;
+ ASSERT_TRUE(key_values->GetString("pkcs8", &pkcs8_hex_string));
+ std::vector<uint8_t> pkcs8_bytes = HexStringToBytes(pkcs8_hex_string);
+
+ // Get the modulus length for the key.
+ int modulus_length_bits = 0;
+ ASSERT_TRUE(key_values->GetInteger("modulusLength", &modulus_length_bits));
+
+ blink::WebCryptoKey private_key;
+
+ // Import the key from JWK.
+ ASSERT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(
+ *key_jwk, CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, blink::WebCryptoKeyUsageSign, &private_key));
+
+ live_keys.push_back(private_key);
+
+ EXPECT_EQ(
+ modulus_length_bits,
+ static_cast<int>(
+ private_key.algorithm().rsaHashedParams()->modulusLengthBits()));
+
+ // Export to PKCS8 and verify that it matches expectation.
+ std::vector<uint8_t> exported_key_pkcs8;
+ ASSERT_EQ(Status::Success(), ExportKey(blink::WebCryptoKeyFormatPkcs8,
+ private_key, &exported_key_pkcs8));
+
+ EXPECT_BYTES_EQ(pkcs8_bytes, exported_key_pkcs8);
+ }
+}
+
+// Import an RSA private key using JWK. Next import a JWK containing the same
+// modulus, but mismatched parameters for the rest. It should NOT be possible
+// that the second import retrieves the first key. See http://crbug.com/378315
+// for how that could happen.
+TEST_F(WebCryptoRsaSsaTest, ImportJwkExistingModulusAndInvalid) {
+ scoped_ptr<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));
+ base::DictionaryValue* key1_jwk;
+ ASSERT_TRUE(key1_props->GetDictionary("jwk", &key1_jwk));
+
+ blink::WebCryptoKey key1;
+ ASSERT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(*key1_jwk,
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, blink::WebCryptoKeyUsageSign, &key1));
+
+ ASSERT_EQ(1024u, key1.algorithm().rsaHashedParams()->modulusLengthBits());
+
+ // 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));
+ base::DictionaryValue* key2_jwk;
+ ASSERT_TRUE(key2_props->GetDictionary("jwk", &key2_jwk));
+ std::string modulus;
+ key1_jwk->GetString("n", &modulus);
+ key2_jwk->SetString("n", modulus);
+
+ // This should fail, as the n,e,d parameters are not consistent. It MUST NOT
+ // somehow return the key created earlier.
+ blink::WebCryptoKey key2;
+ ASSERT_EQ(Status::OperationError(),
+ ImportKeyJwkFromDict(*key2_jwk,
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, blink::WebCryptoKeyUsageSign, &key2));
+}
+
+TEST_F(WebCryptoRsaSsaTest, GenerateKeyPairRsa) {
+ // Note: using unrealistic short key lengths here to avoid bogging down tests.
+
+ // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation (sha256)
+ const unsigned int modulus_length = 256;
+ const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
+ blink::WebCryptoAlgorithm algorithm = CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256, modulus_length, public_exponent);
+ bool extractable = true;
+ const blink::WebCryptoKeyUsageMask public_usages =
+ blink::WebCryptoKeyUsageVerify;
+ const blink::WebCryptoKeyUsageMask private_usages =
+ blink::WebCryptoKeyUsageSign;
+ const blink::WebCryptoKeyUsageMask usages = public_usages | private_usages;
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ EXPECT_EQ(Status::Success(), GenerateKeyPair(algorithm, extractable, usages,
+ &public_key, &private_key));
+ ASSERT_FALSE(public_key.isNull());
+ ASSERT_FALSE(private_key.isNull());
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
+ EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type());
+ EXPECT_EQ(modulus_length,
+ public_key.algorithm().rsaHashedParams()->modulusLengthBits());
+ EXPECT_EQ(modulus_length,
+ private_key.algorithm().rsaHashedParams()->modulusLengthBits());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256,
+ public_key.algorithm().rsaHashedParams()->hash().id());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256,
+ private_key.algorithm().rsaHashedParams()->hash().id());
+ EXPECT_TRUE(public_key.extractable());
+ EXPECT_EQ(extractable, private_key.extractable());
+ EXPECT_EQ(public_usages, public_key.usages());
+ EXPECT_EQ(private_usages, private_key.usages());
+
+ // Try exporting the generated key pair, and then re-importing to verify that
+ // the exported data was valid.
+ std::vector<uint8_t> public_key_spki;
+ EXPECT_EQ(Status::Success(), ExportKey(blink::WebCryptoKeyFormatSpki,
+ public_key, &public_key_spki));
+
+ public_key = blink::WebCryptoKey::createNull();
+ ASSERT_EQ(
+ Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatSpki, CryptoData(public_key_spki),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, public_usages, &public_key));
+ EXPECT_EQ(modulus_length,
+ public_key.algorithm().rsaHashedParams()->modulusLengthBits());
+
+ std::vector<uint8_t> private_key_pkcs8;
+ EXPECT_EQ(Status::Success(), ExportKey(blink::WebCryptoKeyFormatPkcs8,
+ private_key, &private_key_pkcs8));
+ private_key = blink::WebCryptoKey::createNull();
+ ASSERT_EQ(
+ Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatPkcs8, CryptoData(private_key_pkcs8),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, private_usages, &private_key));
+ EXPECT_EQ(modulus_length,
+ private_key.algorithm().rsaHashedParams()->modulusLengthBits());
+
+ // Fail with bad modulus.
+ algorithm = CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256, 0, public_exponent);
+ EXPECT_EQ(Status::ErrorGenerateRsaUnsupportedModulus(),
+ GenerateKeyPair(algorithm, extractable, usages, &public_key,
+ &private_key));
+
+ // Fail with bad exponent: larger than unsigned long.
+ unsigned int exponent_length = sizeof(unsigned long) + 1; // NOLINT
+ const std::vector<uint8_t> long_exponent(exponent_length, 0x01);
+ algorithm = CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256, modulus_length, long_exponent);
+ EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
+ GenerateKeyPair(algorithm, extractable, usages, &public_key,
+ &private_key));
+
+ // Fail with bad exponent: empty.
+ const std::vector<uint8_t> empty_exponent;
+ algorithm = CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256, modulus_length, empty_exponent);
+ EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
+ GenerateKeyPair(algorithm, extractable, usages, &public_key,
+ &private_key));
+
+ // Fail with bad exponent: all zeros.
+ std::vector<uint8_t> exponent_with_leading_zeros(15, 0x00);
+ algorithm = CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256, modulus_length,
+ exponent_with_leading_zeros);
+ EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
+ GenerateKeyPair(algorithm, extractable, usages, &public_key,
+ &private_key));
+
+ // Key generation success using exponent with leading zeros.
+ exponent_with_leading_zeros.insert(exponent_with_leading_zeros.end(),
+ public_exponent.begin(),
+ public_exponent.end());
+ algorithm = CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256, modulus_length,
+ exponent_with_leading_zeros);
+ EXPECT_EQ(Status::Success(), GenerateKeyPair(algorithm, extractable, usages,
+ &public_key, &private_key));
+ EXPECT_FALSE(public_key.isNull());
+ EXPECT_FALSE(private_key.isNull());
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
+ EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type());
+ EXPECT_TRUE(public_key.extractable());
+ EXPECT_EQ(extractable, private_key.extractable());
+ EXPECT_EQ(public_usages, public_key.usages());
+ EXPECT_EQ(private_usages, private_key.usages());
+
+ // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation (sha1)
+ algorithm = CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha1, modulus_length, public_exponent);
+ EXPECT_EQ(Status::Success(), GenerateKeyPair(algorithm, false, usages,
+ &public_key, &private_key));
+ EXPECT_FALSE(public_key.isNull());
+ EXPECT_FALSE(private_key.isNull());
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
+ EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type());
+ EXPECT_EQ(modulus_length,
+ public_key.algorithm().rsaHashedParams()->modulusLengthBits());
+ EXPECT_EQ(modulus_length,
+ private_key.algorithm().rsaHashedParams()->modulusLengthBits());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha1,
+ public_key.algorithm().rsaHashedParams()->hash().id());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha1,
+ private_key.algorithm().rsaHashedParams()->hash().id());
+ // Even though "extractable" was set to false, the public key remains
+ // extractable.
+ EXPECT_TRUE(public_key.extractable());
+ EXPECT_FALSE(private_key.extractable());
+ EXPECT_EQ(public_usages, public_key.usages());
+ EXPECT_EQ(private_usages, private_key.usages());
+
+ // Exporting a private key as SPKI format doesn't make sense. However this
+ // will first fail because the key is not extractable.
+ std::vector<uint8_t> output;
+ EXPECT_EQ(Status::ErrorKeyNotExtractable(),
+ ExportKey(blink::WebCryptoKeyFormatSpki, private_key, &output));
+
+ // Re-generate an extractable private_key and try to export it as SPKI format.
+ // This should fail since spki is for public keys.
+ EXPECT_EQ(Status::Success(), GenerateKeyPair(algorithm, true, usages,
+ &public_key, &private_key));
+ EXPECT_EQ(Status::ErrorUnexpectedKeyType(),
+ ExportKey(blink::WebCryptoKeyFormatSpki, private_key, &output));
+}
+
+TEST_F(WebCryptoRsaSsaTest, GenerateKeyPairRsaBadModulusLength) {
+ const unsigned int kBadModulusBits[] = {
+ 0,
+ 248, // Too small.
+ 257, // Not a multiple of 8.
+ 1023, // Not a multiple of 8.
+ 0xFFFFFFFF, // Too big.
+ 16384 + 8, // 16384 is the maxmimum length that NSS succeeds for.
+ };
+
+ const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
+
+ for (size_t i = 0; i < arraysize(kBadModulusBits); ++i) {
+ const unsigned int modulus_length_bits = kBadModulusBits[i];
+ blink::WebCryptoAlgorithm algorithm = CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256, modulus_length_bits,
+ public_exponent);
+ bool extractable = true;
+ const blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign;
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ EXPECT_EQ(Status::ErrorGenerateRsaUnsupportedModulus(),
+ GenerateKeyPair(algorithm, extractable, usages, &public_key,
+ &private_key));
+ }
+}
+
+// Try generating RSA key pairs using unsupported public exponents. Only
+// exponents of 3 and 65537 are supported. Although OpenSSL can support other
+// values, it can also hang when given invalid exponents. To avoid hanging, use
+// a whitelist of known safe exponents.
+TEST_F(WebCryptoRsaSsaTest, GenerateKeyPairRsaBadExponent) {
+ const unsigned int modulus_length = 1024;
+
+ const char* const kPublicExponents[] = {
+ "11", // 17 - This is a valid public exponent, but currently disallowed.
+ "00",
+ "01",
+ "02",
+ "010000", // 65536
+ };
+
+ for (size_t i = 0; i < arraysize(kPublicExponents); ++i) {
+ SCOPED_TRACE(i);
+ blink::WebCryptoAlgorithm algorithm = CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256, modulus_length,
+ HexStringToBytes(kPublicExponents[i]));
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
+ GenerateKeyPair(algorithm, true, blink::WebCryptoKeyUsageSign,
+ &public_key, &private_key));
+ }
+}
+
+TEST_F(WebCryptoRsaSsaTest, SignVerifyFailures) {
+ // Import a key pair.
+ blink::WebCryptoAlgorithm import_algorithm =
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha1);
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+ ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
+ HexStringToBytes(kPublicKeySpkiDerHex),
+ HexStringToBytes(kPrivateKeyPkcs8DerHex), import_algorithm, false,
+ blink::WebCryptoKeyUsageVerify, blink::WebCryptoKeyUsageSign, &public_key,
+ &private_key));
+
+ blink::WebCryptoAlgorithm algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5);
+
+ std::vector<uint8_t> signature;
+ bool signature_match;
+
+ // Compute a signature.
+ const std::vector<uint8_t> data = HexStringToBytes("010203040506070809");
+ ASSERT_EQ(Status::Success(),
+ Sign(algorithm, private_key, CryptoData(data), &signature));
+
+ // Ensure truncated signature does not verify by passing one less byte.
+ EXPECT_EQ(Status::Success(),
+ Verify(algorithm, public_key,
+ CryptoData(vector_as_array(&signature),
+ static_cast<unsigned int>(signature.size()) - 1),
+ CryptoData(data), &signature_match));
+ EXPECT_FALSE(signature_match);
+
+ // Ensure truncated signature does not verify by passing no bytes.
+ EXPECT_EQ(Status::Success(), Verify(algorithm, public_key, CryptoData(),
+ CryptoData(data), &signature_match));
+ EXPECT_FALSE(signature_match);
+
+ // Ensure corrupted signature does not verify.
+ std::vector<uint8_t> corrupt_sig = signature;
+ corrupt_sig[corrupt_sig.size() / 2] ^= 0x1;
+ EXPECT_EQ(Status::Success(),
+ Verify(algorithm, public_key, CryptoData(corrupt_sig),
+ CryptoData(data), &signature_match));
+ EXPECT_FALSE(signature_match);
+
+ // Ensure signatures that are greater than the modulus size fail.
+ const unsigned int long_message_size_bytes = 1024;
+ DCHECK_GT(long_message_size_bytes, kModulusLengthBits / 8);
+ const unsigned char kLongSignature[long_message_size_bytes] = {0};
+ EXPECT_EQ(Status::Success(),
+ Verify(algorithm, public_key,
+ CryptoData(kLongSignature, sizeof(kLongSignature)),
+ CryptoData(data), &signature_match));
+ EXPECT_FALSE(signature_match);
+
+ // Ensure that signing and verifying with an incompatible algorithm fails.
+ algorithm = CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaOaep);
+
+ EXPECT_EQ(Status::ErrorUnexpected(),
+ Sign(algorithm, private_key, CryptoData(data), &signature));
+ EXPECT_EQ(Status::ErrorUnexpected(),
+ Verify(algorithm, public_key, CryptoData(signature),
+ CryptoData(data), &signature_match));
+
+ // Some crypto libraries (NSS) can automatically select the RSA SSA inner hash
+ // based solely on the contents of the input signature data. In the Web Crypto
+ // implementation, the inner hash should be specified uniquely by the key
+ // algorithm parameter. To validate this behavior, call Verify with a computed
+ // signature that used one hash type (SHA-1), but pass in a key with a
+ // different inner hash type (SHA-256). If the hash type is determined by the
+ // signature itself (undesired), the verify will pass, while if the hash type
+ // is specified by the key algorithm (desired), the verify will fail.
+
+ // Compute a signature using SHA-1 as the inner hash.
+ EXPECT_EQ(Status::Success(),
+ Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5),
+ private_key, CryptoData(data), &signature));
+
+ blink::WebCryptoKey public_key_256;
+ EXPECT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatSpki,
+ CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, blink::WebCryptoKeyUsageVerify, &public_key_256));
+
+ // Now verify using an algorithm whose inner hash is SHA-256, not SHA-1. The
+ // signature should not verify.
+ // NOTE: public_key was produced by generateKey, and so its associated
+ // algorithm has WebCryptoRsaKeyGenParams and not WebCryptoRsaSsaParams. Thus
+ // it has no inner hash to conflict with the input algorithm.
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha1,
+ private_key.algorithm().rsaHashedParams()->hash().id());
+ EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256,
+ public_key_256.algorithm().rsaHashedParams()->hash().id());
+
+ bool is_match;
+ EXPECT_EQ(Status::Success(),
+ Verify(CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5),
+ public_key_256, CryptoData(signature), CryptoData(data),
+ &is_match));
+ EXPECT_FALSE(is_match);
+}
+
+TEST_F(WebCryptoRsaSsaTest, SignVerifyKnownAnswer) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("pkcs1v15_sign.json", &tests));
+
+ // Import the key pair.
+ blink::WebCryptoAlgorithm import_algorithm =
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha1);
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+ ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
+ HexStringToBytes(kPublicKeySpkiDerHex),
+ HexStringToBytes(kPrivateKeyPkcs8DerHex), import_algorithm, false,
+ blink::WebCryptoKeyUsageVerify, blink::WebCryptoKeyUsageSign, &public_key,
+ &private_key));
+
+ blink::WebCryptoAlgorithm algorithm =
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5);
+
+ // 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) {
+ SCOPED_TRACE(test_index);
+
+ base::DictionaryValue* test;
+ ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+
+ std::vector<uint8_t> test_message =
+ GetBytesFromHexString(test, "message_hex");
+ std::vector<uint8_t> test_signature =
+ GetBytesFromHexString(test, "signature_hex");
+
+ signature.clear();
+ ASSERT_EQ(Status::Success(), Sign(algorithm, private_key,
+ CryptoData(test_message), &signature));
+ EXPECT_BYTES_EQ(test_signature, signature);
+
+ bool is_match = false;
+ ASSERT_EQ(Status::Success(),
+ Verify(algorithm, public_key, CryptoData(test_signature),
+ CryptoData(test_message), &is_match));
+ EXPECT_TRUE(is_match);
+ }
+}
+
+// Try importing an RSA-SSA public key with unsupported key usages using SPKI
+// format. RSA-SSA public keys only support the 'verify' usage.
+TEST_F(WebCryptoRsaSsaTest, ImportRsaSsaPublicKeyBadUsage_SPKI) {
+ const blink::WebCryptoAlgorithm algorithm =
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256);
+
+ blink::WebCryptoKeyUsageMask bad_usages[] = {
+ blink::WebCryptoKeyUsageSign,
+ blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
+ blink::WebCryptoKeyUsageEncrypt,
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
+ };
+
+ for (size_t i = 0; i < arraysize(bad_usages); ++i) {
+ SCOPED_TRACE(i);
+
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
+ ImportKey(blink::WebCryptoKeyFormatSpki,
+ CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
+ algorithm, false, bad_usages[i], &public_key));
+ }
+}
+
+// Try importing an RSA-SSA public key with unsupported key usages using JWK
+// format. RSA-SSA public keys only support the 'verify' usage.
+TEST_F(WebCryptoRsaSsaTest, ImportRsaSsaPublicKeyBadUsage_JWK) {
+ const blink::WebCryptoAlgorithm algorithm =
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256);
+
+ blink::WebCryptoKeyUsageMask bad_usages[] = {
+ blink::WebCryptoKeyUsageSign,
+ blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
+ blink::WebCryptoKeyUsageEncrypt,
+ blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
+ };
+
+ base::DictionaryValue dict;
+ RestoreJwkRsaDictionary(&dict);
+ dict.Remove("use", NULL);
+ dict.SetString("alg", "RS256");
+
+ for (size_t i = 0; i < arraysize(bad_usages); ++i) {
+ SCOPED_TRACE(i);
+
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
+ ImportKeyJwkFromDict(dict, algorithm, false, bad_usages[i],
+ &public_key));
+ }
+}
+
+// Generate an RSA-SSA key pair with invalid usages. RSA-SSA supports:
+// 'sign', 'verify'
+TEST_F(WebCryptoRsaSsaTest, GenerateKeyBadUsages) {
+ blink::WebCryptoKeyUsageMask bad_usages[] = {
+ blink::WebCryptoKeyUsageDecrypt,
+ blink::WebCryptoKeyUsageVerify | blink::WebCryptoKeyUsageDecrypt,
+ blink::WebCryptoKeyUsageWrapKey,
+ };
+
+ const unsigned int modulus_length = 256;
+ const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
+
+ for (size_t i = 0; i < arraysize(bad_usages); ++i) {
+ SCOPED_TRACE(i);
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
+ GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256,
+ modulus_length, public_exponent),
+ true, bad_usages[i], &public_key, &private_key));
+ }
+}
+
+// Generate an RSA-SSA key pair. The public and private keys should select the
+// key usages which are applicable, and not have the exact same usages as was
+// specified to GenerateKey
+TEST_F(WebCryptoRsaSsaTest, GenerateKeyPairIntersectUsages) {
+ const unsigned int modulus_length = 256;
+ const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ ASSERT_EQ(Status::Success(),
+ GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256,
+ modulus_length, public_exponent),
+ true, blink::WebCryptoKeyUsageSign |
+ blink::WebCryptoKeyUsageVerify,
+ &public_key, &private_key));
+
+ EXPECT_EQ(blink::WebCryptoKeyUsageVerify, public_key.usages());
+ EXPECT_EQ(blink::WebCryptoKeyUsageSign, private_key.usages());
+
+ // Try again but this time without the Verify usages.
+ ASSERT_EQ(Status::Success(),
+ GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256,
+ modulus_length, public_exponent),
+ true, blink::WebCryptoKeyUsageSign, &public_key,
+ &private_key));
+
+ EXPECT_EQ(0, public_key.usages());
+ EXPECT_EQ(blink::WebCryptoKeyUsageSign, private_key.usages());
+}
+
+TEST_F(WebCryptoRsaSsaTest, GenerateKeyPairEmptyUsages) {
+ const unsigned int modulus_length = 256;
+ const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256,
+ modulus_length, public_exponent),
+ true, 0, &public_key, &private_key));
+}
+
+TEST_F(WebCryptoRsaSsaTest, ImportKeyEmptyUsages) {
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey private_key;
+
+ // Public without usage does not throw an error.
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatSpki,
+ CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, 0, &public_key));
+ EXPECT_EQ(0, public_key.usages());
+
+ // Private empty usage will throw an error.
+ ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ ImportKey(blink::WebCryptoKeyFormatPkcs8,
+ CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, 0, &private_key));
+
+ std::vector<uint8_t> public_jwk;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &public_jwk));
+
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(public_jwk),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, 0, &public_key));
+ EXPECT_EQ(0, public_key.usages());
+
+ // With correct usage to get correct imported private_key
+ std::vector<uint8_t> private_jwk;
+ ImportKey(
+ blink::WebCryptoKeyFormatPkcs8,
+ CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, blink::WebCryptoKeyUsageSign, &private_key);
+
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, private_key, &private_jwk));
+
+ ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(private_jwk),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha1),
+ true, 0, &private_key));
+}
+
+TEST_F(WebCryptoRsaSsaTest, ImportExportJwkRsaPublicKey) {
+ struct TestCase {
+ const blink::WebCryptoAlgorithmId hash;
+ const blink::WebCryptoKeyUsageMask usage;
+ const char* const jwk_alg;
+ };
+ const TestCase kTests[] = {
+ {blink::WebCryptoAlgorithmIdSha1, blink::WebCryptoKeyUsageVerify, "RS1"},
+ {blink::WebCryptoAlgorithmIdSha256,
+ blink::WebCryptoKeyUsageVerify,
+ "RS256"},
+ {blink::WebCryptoAlgorithmIdSha384,
+ blink::WebCryptoKeyUsageVerify,
+ "RS384"},
+ {blink::WebCryptoAlgorithmIdSha512,
+ blink::WebCryptoKeyUsageVerify,
+ "RS512"}};
+
+ for (size_t test_index = 0; test_index < arraysize(kTests); ++test_index) {
+ SCOPED_TRACE(test_index);
+ const TestCase& test = kTests[test_index];
+
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, test.hash);
+
+ // Import the spki to create a public key
+ blink::WebCryptoKey public_key;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatSpki,
+ CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
+ import_algorithm, true, test.usage, &public_key));
+
+ // Export the public key as JWK and verify its contents
+ std::vector<uint8_t> jwk;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &jwk));
+ EXPECT_TRUE(VerifyPublicJwk(jwk, test.jwk_alg, kPublicKeyModulusHex,
+ kPublicKeyExponentHex, test.usage));
+
+ // Import the JWK back in to create a new key
+ blink::WebCryptoKey public_key2;
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(jwk),
+ import_algorithm, true, test.usage, &public_key2));
+ ASSERT_TRUE(public_key2.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key2.type());
+ EXPECT_TRUE(public_key2.extractable());
+ EXPECT_EQ(import_algorithm.id(), public_key2.algorithm().id());
+
+ // Export the new key as spki and compare to the original.
+ std::vector<uint8_t> spki;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatSpki, public_key2, &spki));
+ EXPECT_BYTES_EQ_HEX(kPublicKeySpkiDerHex, CryptoData(spki));
+ }
+}
+
+TEST_F(WebCryptoRsaSsaTest, ImportJwkRsaFailures) {
+ base::DictionaryValue dict;
+ RestoreJwkRsaDictionary(&dict);
+ blink::WebCryptoAlgorithm algorithm =
+ CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256);
+ blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageVerify;
+ blink::WebCryptoKey key;
+
+ // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent)
+ // entry, while an RSA private key must have those plus at least a "d"
+ // (private exponent) entry.
+ // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
+ // section 6.3.
+
+ // Baseline pass.
+ EXPECT_EQ(Status::Success(),
+ ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
+ EXPECT_EQ(algorithm.id(), key.algorithm().id());
+ EXPECT_FALSE(key.extractable());
+ EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages());
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type());
+
+ // The following are specific failure cases for when kty = "RSA".
+
+ // Fail if either "n" or "e" is not present or malformed.
+ const std::string kKtyParmName[] = {"n", "e"};
+ for (size_t idx = 0; idx < arraysize(kKtyParmName); ++idx) {
+ // Fail on missing parameter.
+ dict.Remove(kKtyParmName[idx], NULL);
+ EXPECT_NE(Status::Success(),
+ ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
+ RestoreJwkRsaDictionary(&dict);
+
+ // Fail on bad b64 parameter encoding.
+ dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0");
+ EXPECT_NE(Status::Success(),
+ ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
+ RestoreJwkRsaDictionary(&dict);
+
+ // Fail on empty parameter.
+ dict.SetString(kKtyParmName[idx], "");
+ EXPECT_EQ(Status::ErrorJwkEmptyBigInteger(kKtyParmName[idx]),
+ ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
+ RestoreJwkRsaDictionary(&dict);
+ }
+}
+
+// Try importing an RSA-SSA key from JWK format, having specified both Sign and
+// Verify usage, and an invalid JWK.
+//
+// The test must fail with a usage error BEFORE attempting to read the JWK data.
+// Although both Sign and Verify are valid usages for RSA-SSA keys, it is
+// invalid to have them both at the same time for one key (since Sign applies to
+// private keys, whereas Verify applies to public keys).
+//
+// If the implementation does not fail fast, this test will crash dereferencing
+// invalid memory.
+TEST_F(WebCryptoRsaSsaTest, ImportRsaSsaJwkBadUsageFailFast) {
+ CryptoData bad_data(NULL, 128); // Invalid buffer of length 128.
+
+ blink::WebCryptoKey key;
+ ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, bad_data,
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, blink::WebCryptoKeyUsageVerify |
+ blink::WebCryptoKeyUsageSign,
+ &key));
+}
+
+// Imports invalid JWK/SPKI/PKCS8 data and verifies that it fails as expected.
+TEST_F(WebCryptoRsaSsaTest, ImportInvalidKeyData) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("bad_rsa_keys.json", &tests));
+
+ 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));
+
+ blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
+ std::vector<uint8_t> key_data =
+ GetKeyDataFromJsonTestCase(test, key_format);
+ std::string test_error;
+ ASSERT_TRUE(test->GetString("error", &test_error));
+
+ blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign;
+ if (key_format == blink::WebCryptoKeyFormatSpki)
+ usages = blink::WebCryptoKeyUsageVerify;
+ blink::WebCryptoKey key;
+ Status status = ImportKey(key_format, CryptoData(key_data),
+ CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
+ blink::WebCryptoAlgorithmIdSha256),
+ true, usages, &key);
+ EXPECT_EQ(test_error, StatusToString(status));
+ }
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/secret_key_util.cc b/chromium/components/webcrypto/algorithms/secret_key_util.cc
new file mode 100644
index 00000000000..dcdecfa19e6
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/secret_key_util.cc
@@ -0,0 +1,91 @@
+// 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/webcrypto/algorithms/secret_key_util.h"
+
+#include <openssl/rand.h>
+
+#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/generate_key_result.h"
+#include "components/webcrypto/jwk.h"
+#include "components/webcrypto/status.h"
+#include "crypto/openssl_util.h"
+
+namespace webcrypto {
+
+Status GenerateWebCryptoSecretKey(const blink::WebCryptoKeyAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ unsigned int keylen_bits,
+ GenerateKeyResult* result) {
+ crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+
+ unsigned int keylen_bytes = NumBitsToBytes(keylen_bits);
+ std::vector<unsigned char> random_bytes(keylen_bytes, 0);
+
+ if (keylen_bytes > 0) {
+ if (!RAND_bytes(vector_as_array(&random_bytes), keylen_bytes))
+ return Status::OperationError();
+ TruncateToBitLength(keylen_bits, &random_bytes);
+ }
+
+ result->AssignSecretKey(blink::WebCryptoKey::create(
+ CreateSymmetricKeyHandle(CryptoData(random_bytes)),
+ blink::WebCryptoKeyTypeSecret, extractable, algorithm, usages));
+
+ return Status::Success();
+}
+
+Status CreateWebCryptoSecretKey(const CryptoData& key_data,
+ const blink::WebCryptoKeyAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoKey* key) {
+ *key = blink::WebCryptoKey::create(CreateSymmetricKeyHandle(key_data),
+ blink::WebCryptoKeyTypeSecret, extractable,
+ algorithm, usages);
+ return Status::Success();
+}
+
+Status CheckSecretKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages) {
+ return CheckKeyCreationUsages(all_possible_usages, actual_usages,
+ EmptyUsagePolicy::REJECT_EMPTY);
+}
+
+void WriteSecretKeyJwk(const CryptoData& raw_key_data,
+ const std::string& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ std::vector<uint8_t>* jwk_key_data) {
+ JwkWriter writer(algorithm, extractable, usages, "oct");
+ writer.SetBytes("k", raw_key_data);
+ writer.ToJson(jwk_key_data);
+}
+
+Status ReadSecretKeyNoExpectedAlgJwk(
+ const CryptoData& key_data,
+ bool expected_extractable,
+ blink::WebCryptoKeyUsageMask expected_usages,
+ std::vector<uint8_t>* raw_key_data,
+ JwkReader* jwk) {
+ Status status = jwk->Init(key_data, expected_extractable, expected_usages,
+ "oct", std::string());
+ if (status.IsError())
+ return status;
+
+ std::string jwk_k_value;
+ status = jwk->GetBytes("k", &jwk_k_value);
+ if (status.IsError())
+ return status;
+ raw_key_data->assign(jwk_k_value.begin(), jwk_k_value.end());
+
+ return Status::Success();
+}
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/secret_key_util.h b/chromium/components/webcrypto/algorithms/secret_key_util.h
new file mode 100644
index 00000000000..cfef769262a
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/secret_key_util.h
@@ -0,0 +1,73 @@
+// 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_WEBCRYPTO_ALGORITHMS_SECRET_KEY_UTIL_
+#define COMPONENTS_WEBCRYPTO_ALGORITHMS_SECRET_KEY_UTIL_
+
+#include <string>
+#include <vector>
+
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
+#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+
+// This file contains functions shared by multiple symmetric key algorithms.
+
+namespace webcrypto {
+
+class CryptoData;
+class GenerateKeyResult;
+class JwkReader;
+class Status;
+
+// Generates a random secret key of the given bit length. If the bit length is
+// not a multiple of 8, then the resulting key will have ceil(keylen_bits / 8)
+// bytes, and the "unused" bits will be set to zero. This function does not do
+// any validation checks on the provided parameters.
+Status GenerateWebCryptoSecretKey(const blink::WebCryptoKeyAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ unsigned int keylen_bits,
+ GenerateKeyResult* result);
+
+// Creates a WebCrypto secret key given the raw data. The provided |key_data|
+// will be copied into the new key. This function does not do any validation
+// checks for the provided parameters.
+Status CreateWebCryptoSecretKey(const CryptoData& key_data,
+ const blink::WebCryptoKeyAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoKey* key);
+
+// Checks that |actual_usages| is a non-empty subset of |all_possible_usages|.
+Status CheckSecretKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages);
+
+// Writes a JWK-formatted symmetric key to |jwk_key_data|.
+// * raw_key_data: The actual key data
+// * algorithm: The JWK algorithm name (i.e. "alg")
+// * extractable: The JWK extractability (i.e. "ext")
+// * usages: The JWK usages (i.e. "key_ops")
+void WriteSecretKeyJwk(const CryptoData& raw_key_data,
+ const std::string& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ std::vector<uint8_t>* jwk_key_data);
+
+// Parses a UTF-8 encoded JWK (key_data), and extracts the key material to
+// |*raw_key_data|. Returns Status::Success() on success, otherwise an error.
+// In order for this to succeed:
+// * expected_extractable must be consistent with the JWK's "ext", if
+// present.
+// * expected_usages must be a subset of the JWK's "key_ops" if present.
+Status ReadSecretKeyNoExpectedAlgJwk(
+ const CryptoData& key_data,
+ bool expected_extractable,
+ blink::WebCryptoKeyUsageMask expected_usages,
+ std::vector<uint8_t>* raw_key_data,
+ JwkReader* jwk);
+
+} // namespace webcrypto
+
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_SECRET_KEY_UTIL_
diff --git a/chromium/components/webcrypto/openssl/sha_openssl.cc b/chromium/components/webcrypto/algorithms/sha.cc
index 18c687a31f5..2d8b544b545 100644
--- a/chromium/components/webcrypto/openssl/sha_openssl.cc
+++ b/chromium/components/webcrypto/algorithms/sha.cc
@@ -2,17 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <vector>
#include <openssl/evp.h>
#include <openssl/sha.h>
+#include <vector>
#include "base/logging.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
+#include "components/webcrypto/algorithms/util.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/openssl/util_openssl.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
@@ -24,9 +23,9 @@ namespace {
// part of WebCrypto, that allows chunks of data to be streamed in before
// computing a SHA-* digest (as opposed to ShaImplementation, which computes
// digests over complete messages)
-class DigestorOpenSsl : public blink::WebCryptoDigestor {
+class DigestorImpl : public blink::WebCryptoDigestor {
public:
- explicit DigestorOpenSsl(blink::WebCryptoAlgorithmId algorithm_id)
+ explicit DigestorImpl(blink::WebCryptoAlgorithmId algorithm_id)
: initialized_(false),
digest_context_(EVP_MD_CTX_create()),
algorithm_id_(algorithm_id) {}
@@ -112,7 +111,7 @@ class ShaImplementation : public AlgorithmImplementation {
Status Digest(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& data,
std::vector<uint8_t>* buffer) const override {
- DigestorOpenSsl digestor(algorithm.id());
+ DigestorImpl digestor(algorithm.id());
Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length());
// http://crbug.com/366427: the spec does not define any other failures for
// digest, so none of the subsequent errors are spec compliant.
@@ -124,13 +123,13 @@ class ShaImplementation : public AlgorithmImplementation {
} // namespace
-AlgorithmImplementation* CreatePlatformShaImplementation() {
- return new ShaImplementation();
+scoped_ptr<AlgorithmImplementation> CreateShaImplementation() {
+ return make_scoped_ptr(new ShaImplementation());
}
-scoped_ptr<blink::WebCryptoDigestor> CreatePlatformDigestor(
+scoped_ptr<blink::WebCryptoDigestor> CreateDigestorImplementation(
blink::WebCryptoAlgorithmId algorithm) {
- return scoped_ptr<blink::WebCryptoDigestor>(new DigestorOpenSsl(algorithm));
+ return scoped_ptr<blink::WebCryptoDigestor>(new DigestorImpl(algorithm));
}
} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/sha_unittest.cc b/chromium/components/webcrypto/algorithms/sha_unittest.cc
new file mode 100644
index 00000000000..4e82d98763c
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/sha_unittest.cc
@@ -0,0 +1,84 @@
+// 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 "base/logging.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+class WebCryptoShaTest : public WebCryptoTestBase {};
+
+TEST_F(WebCryptoShaTest, DigestSampleSets) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("sha.json", &tests));
+
+ 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));
+
+ blink::WebCryptoAlgorithm test_algorithm =
+ GetDigestAlgorithm(test, "algorithm");
+ std::vector<uint8_t> test_input = GetBytesFromHexString(test, "input");
+ std::vector<uint8_t> test_output = GetBytesFromHexString(test, "output");
+
+ std::vector<uint8_t> output;
+ ASSERT_EQ(Status::Success(),
+ Digest(test_algorithm, CryptoData(test_input), &output));
+ EXPECT_BYTES_EQ(test_output, output);
+ }
+}
+
+TEST_F(WebCryptoShaTest, DigestSampleSetsInChunks) {
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("sha.json", &tests));
+
+ 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));
+
+ blink::WebCryptoAlgorithm test_algorithm =
+ GetDigestAlgorithm(test, "algorithm");
+ std::vector<uint8_t> test_input = GetBytesFromHexString(test, "input");
+ std::vector<uint8_t> test_output = GetBytesFromHexString(test, "output");
+
+ // Test the chunk version of the digest functions. Test with 129 byte chunks
+ // because the SHA-512 chunk size is 128 bytes.
+ unsigned char* output;
+ unsigned int output_length;
+ static const size_t kChunkSizeBytes = 129;
+ size_t length = test_input.size();
+ scoped_ptr<blink::WebCryptoDigestor> digestor(
+ CreateDigestor(test_algorithm.id()));
+ std::vector<uint8_t>::iterator begin = test_input.begin();
+ size_t chunk_index = 0;
+ while (begin != test_input.end()) {
+ size_t chunk_length = std::min(kChunkSizeBytes, length - chunk_index);
+ std::vector<uint8_t> chunk(begin, begin + chunk_length);
+ ASSERT_TRUE(chunk.size() > 0);
+ EXPECT_TRUE(digestor->consume(vector_as_array(&chunk),
+ static_cast<unsigned int>(chunk.size())));
+ chunk_index = chunk_index + chunk_length;
+ begin = begin + chunk_length;
+ }
+ EXPECT_TRUE(digestor->finish(output, output_length));
+ EXPECT_BYTES_EQ(test_output, CryptoData(output, output_length));
+ }
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/test_helpers.cc b/chromium/components/webcrypto/algorithms/test_helpers.cc
new file mode 100644
index 00000000000..22db00fdd2b
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/test_helpers.cc
@@ -0,0 +1,684 @@
+// 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/webcrypto/algorithms/test_helpers.h"
+
+#include <algorithm>
+
+#include "base/files/file_util.h"
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "components/test_runner/test_common.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/generate_key_result.h"
+#include "components/webcrypto/jwk.h"
+#include "components/webcrypto/status.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+#include "third_party/re2/re2/re2.h"
+
+namespace webcrypto {
+
+// static
+void WebCryptoTestBase::SetUpTestCase() {
+ test_runner::EnsureBlinkInitialized();
+}
+
+void PrintTo(const Status& status, ::std::ostream* os) {
+ *os << StatusToString(status);
+}
+
+bool operator==(const Status& a, const Status& b) {
+ if (a.IsSuccess() != b.IsSuccess())
+ return false;
+ if (a.IsSuccess())
+ return true;
+ return a.error_type() == b.error_type() &&
+ a.error_details() == b.error_details();
+}
+
+bool operator!=(const Status& a, const Status& b) {
+ return !(a == b);
+}
+
+void PrintTo(const CryptoData& data, ::std::ostream* os) {
+ *os << "[" << base::HexEncode(data.bytes(), data.byte_length()) << "]";
+}
+
+bool operator==(const CryptoData& a, const CryptoData& b) {
+ return a.byte_length() == b.byte_length() &&
+ memcmp(a.bytes(), b.bytes(), a.byte_length()) == 0;
+}
+
+bool operator!=(const CryptoData& a, const CryptoData& b) {
+ return !(a == b);
+}
+
+static std::string ErrorTypeToString(blink::WebCryptoErrorType type) {
+ switch (type) {
+ case blink::WebCryptoErrorTypeNotSupported:
+ return "NotSupported";
+ case blink::WebCryptoErrorTypeType:
+ return "TypeError";
+ case blink::WebCryptoErrorTypeData:
+ return "DataError";
+ case blink::WebCryptoErrorTypeSyntax:
+ return "SyntaxError";
+ case blink::WebCryptoErrorTypeOperation:
+ return "OperationError";
+ case blink::WebCryptoErrorTypeInvalidAccess:
+ return "InvalidAccess";
+ default:
+ return "?";
+ }
+}
+
+std::string StatusToString(const Status& status) {
+ if (status.IsSuccess())
+ return "Success";
+
+ std::string result = ErrorTypeToString(status.error_type());
+ if (!status.error_details().empty())
+ result += ": " + status.error_details();
+ return result;
+}
+
+blink::WebCryptoAlgorithm CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmId algorithm_id,
+ const blink::WebCryptoAlgorithmId hash_id,
+ unsigned int modulus_length,
+ const std::vector<uint8_t>& public_exponent) {
+ DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ algorithm_id, new blink::WebCryptoRsaHashedKeyGenParams(
+ CreateAlgorithm(hash_id), modulus_length,
+ vector_as_array(&public_exponent),
+ static_cast<unsigned int>(public_exponent.size())));
+}
+
+std::vector<uint8_t> Corrupted(const std::vector<uint8_t>& input) {
+ std::vector<uint8_t> corrupted_data(input);
+ if (corrupted_data.empty())
+ corrupted_data.push_back(0);
+ corrupted_data[corrupted_data.size() / 2] ^= 0x01;
+ return corrupted_data;
+}
+
+std::vector<uint8_t> HexStringToBytes(const std::string& hex) {
+ std::vector<uint8_t> bytes;
+ base::HexStringToBytes(hex, &bytes);
+ return bytes;
+}
+
+std::vector<uint8_t> MakeJsonVector(const std::string& json_string) {
+ return std::vector<uint8_t>(json_string.begin(), json_string.end());
+}
+
+std::vector<uint8_t> MakeJsonVector(const base::DictionaryValue& dict) {
+ std::string json;
+ base::JSONWriter::Write(dict, &json);
+ return MakeJsonVector(json);
+}
+
+::testing::AssertionResult ReadJsonTestFile(const char* test_file_name,
+ scoped_ptr<base::Value>* value) {
+ base::FilePath test_data_dir;
+ if (!PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir))
+ return ::testing::AssertionFailure() << "Couldn't retrieve test dir";
+
+ base::FilePath file_path = test_data_dir.AppendASCII("components")
+ .AppendASCII("test")
+ .AppendASCII("data")
+ .AppendASCII("webcrypto")
+ .AppendASCII(test_file_name);
+
+ std::string file_contents;
+ if (!base::ReadFileToString(file_path, &file_contents)) {
+ return ::testing::AssertionFailure()
+ << "Couldn't read test file: " << file_path.value();
+ }
+
+ // Strip C++ style comments out of the "json" file, otherwise it cannot be
+ // parsed.
+ re2::RE2::GlobalReplace(&file_contents, re2::RE2("\\s*//.*"), "");
+
+ // Parse the JSON to a dictionary.
+ *value = base::JSONReader::Read(file_contents);
+ if (!value->get()) {
+ return ::testing::AssertionFailure()
+ << "Couldn't parse test file JSON: " << file_path.value();
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult ReadJsonTestFileToList(
+ const char* test_file_name,
+ scoped_ptr<base::ListValue>* list) {
+ // Read the JSON.
+ scoped_ptr<base::Value> json;
+ ::testing::AssertionResult result = ReadJsonTestFile(test_file_name, &json);
+ if (!result)
+ return result;
+
+ // Cast to an ListValue.
+ base::ListValue* list_value = NULL;
+ if (!json->GetAsList(&list_value) || !list_value)
+ return ::testing::AssertionFailure() << "The JSON was not a list";
+
+ list->reset(list_value);
+ ignore_result(json.release());
+
+ return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult ReadJsonTestFileToDictionary(
+ const char* test_file_name,
+ scoped_ptr<base::DictionaryValue>* dict) {
+ // Read the JSON.
+ scoped_ptr<base::Value> json;
+ ::testing::AssertionResult result = ReadJsonTestFile(test_file_name, &json);
+ if (!result)
+ return result;
+
+ // Cast to an DictionaryValue.
+ base::DictionaryValue* dict_value = NULL;
+ if (!json->GetAsDictionary(&dict_value) || !dict_value)
+ return ::testing::AssertionFailure() << "The JSON was not a dictionary";
+
+ dict->reset(dict_value);
+ ignore_result(json.release());
+
+ return ::testing::AssertionSuccess();
+}
+
+std::vector<uint8_t> GetBytesFromHexString(const base::DictionaryValue* dict,
+ const std::string& property_name) {
+ std::string hex_string;
+ if (!dict->GetString(property_name, &hex_string)) {
+ ADD_FAILURE() << "Couldn't get string property: " << property_name;
+ return std::vector<uint8_t>();
+ }
+
+ return HexStringToBytes(hex_string);
+}
+
+blink::WebCryptoAlgorithm GetDigestAlgorithm(const base::DictionaryValue* dict,
+ const char* property_name) {
+ std::string algorithm_name;
+ if (!dict->GetString(property_name, &algorithm_name)) {
+ ADD_FAILURE() << "Couldn't get string property: " << property_name;
+ return blink::WebCryptoAlgorithm::createNull();
+ }
+
+ struct {
+ const char* name;
+ blink::WebCryptoAlgorithmId id;
+ } kDigestNameToId[] = {
+ {"sha-1", blink::WebCryptoAlgorithmIdSha1},
+ {"sha-256", blink::WebCryptoAlgorithmIdSha256},
+ {"sha-384", blink::WebCryptoAlgorithmIdSha384},
+ {"sha-512", blink::WebCryptoAlgorithmIdSha512},
+ };
+
+ for (size_t i = 0; i < arraysize(kDigestNameToId); ++i) {
+ if (kDigestNameToId[i].name == algorithm_name)
+ return CreateAlgorithm(kDigestNameToId[i].id);
+ }
+
+ return blink::WebCryptoAlgorithm::createNull();
+}
+
+// Creates a comparator for |bufs| which operates on indices rather than values.
+class CompareUsingIndex {
+ public:
+ explicit CompareUsingIndex(const std::vector<std::vector<uint8_t>>* bufs)
+ : bufs_(bufs) {}
+
+ bool operator()(size_t i1, size_t i2) { return (*bufs_)[i1] < (*bufs_)[i2]; }
+
+ private:
+ const std::vector<std::vector<uint8_t>>* bufs_;
+};
+
+bool CopiesExist(const std::vector<std::vector<uint8_t>>& bufs) {
+ // Sort the indices of |bufs| into a separate vector. This reduces the amount
+ // of data copied versus sorting |bufs| directly.
+ std::vector<size_t> sorted_indices(bufs.size());
+ for (size_t i = 0; i < sorted_indices.size(); ++i)
+ sorted_indices[i] = i;
+ std::sort(sorted_indices.begin(), sorted_indices.end(),
+ CompareUsingIndex(&bufs));
+
+ // Scan for adjacent duplicates.
+ for (size_t i = 1; i < sorted_indices.size(); ++i) {
+ if (bufs[sorted_indices[i]] == bufs[sorted_indices[i - 1]])
+ return true;
+ }
+ return false;
+}
+
+blink::WebCryptoAlgorithm CreateAesKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmId aes_alg_id,
+ unsigned short length) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ aes_alg_id, new blink::WebCryptoAesKeyGenParams(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
+// NIST test vectors at
+// ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt
+const unsigned int kModulusLengthBits = 1024;
+const char* const kPublicKeySpkiDerHex =
+ "30819f300d06092a864886f70d010101050003818d0030818902818100a5"
+ "6e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad9"
+ "91d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfc"
+ "e0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e"
+ "6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cf"
+ "fb2249bd9a21370203010001";
+const char* const kPrivateKeyPkcs8DerHex =
+ "30820275020100300d06092a864886f70d01010105000482025f3082025b"
+ "02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52"
+ "a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab"
+ "7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921c"
+ "b23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef"
+ "22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d"
+ "4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c"
+ "568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee"
+ "896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31"
+ "b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b3"
+ "25024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e8629"
+ "6b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b"
+ "3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde12"
+ "3fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc72"
+ "3e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca"
+ "5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8d"
+ "d3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa71"
+ "2049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd"
+ "48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027"
+ "156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319"
+ "584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24"
+ "a79f4d";
+// The modulus and exponent (in hex) of kPublicKeySpkiDerHex
+const char* const kPublicKeyModulusHex =
+ "A56E4A0E701017589A5187DC7EA841D156F2EC0E36AD52A44DFEB1E61F7AD991D8C51056"
+ "FFEDB162B4C0F283A12A88A394DFF526AB7291CBB307CEABFCE0B1DFD5CD9508096D5B2B"
+ "8B6DF5D671EF6377C0921CB23C270A70E2598E6FF89D19F105ACC2D3F0CB35F29280E138"
+ "6B6F64C4EF22E1E1F20D0CE8CFFB2249BD9A2137";
+const char* const kPublicKeyExponentHex = "010001";
+
+blink::WebCryptoKey ImportSecretKeyFromRaw(
+ const std::vector<uint8_t>& key_raw,
+ const blink::WebCryptoAlgorithm& algorithm,
+ blink::WebCryptoKeyUsageMask usage) {
+ blink::WebCryptoKey key;
+ bool extractable = true;
+ EXPECT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(key_raw),
+ algorithm, extractable, usage, &key));
+
+ EXPECT_FALSE(key.isNull());
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ EXPECT_EQ(algorithm.id(), key.algorithm().id());
+ EXPECT_EQ(extractable, key.extractable());
+ EXPECT_EQ(usage, key.usages());
+ return key;
+}
+
+void ImportRsaKeyPair(const std::vector<uint8_t>& spki_der,
+ const std::vector<uint8_t>& pkcs8_der,
+ const blink::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask public_key_usages,
+ blink::WebCryptoKeyUsageMask private_key_usages,
+ blink::WebCryptoKey* public_key,
+ blink::WebCryptoKey* private_key) {
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatSpki, CryptoData(spki_der),
+ algorithm, true, public_key_usages, public_key));
+ EXPECT_FALSE(public_key->isNull());
+ EXPECT_TRUE(public_key->handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key->type());
+ EXPECT_EQ(algorithm.id(), public_key->algorithm().id());
+ EXPECT_TRUE(public_key->extractable());
+ EXPECT_EQ(public_key_usages, public_key->usages());
+
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatPkcs8, CryptoData(pkcs8_der),
+ algorithm, extractable, private_key_usages, private_key));
+ EXPECT_FALSE(private_key->isNull());
+ EXPECT_TRUE(private_key->handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key->type());
+ EXPECT_EQ(algorithm.id(), private_key->algorithm().id());
+ EXPECT_EQ(extractable, private_key->extractable());
+ EXPECT_EQ(private_key_usages, private_key->usages());
+}
+
+Status ImportKeyJwkFromDict(const base::DictionaryValue& dict,
+ const blink::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoKey* key) {
+ return ImportKey(blink::WebCryptoKeyFormatJwk,
+ CryptoData(MakeJsonVector(dict)), algorithm, extractable,
+ usages, key);
+}
+
+scoped_ptr<base::DictionaryValue> GetJwkDictionary(
+ const std::vector<uint8_t>& json) {
+ base::StringPiece json_string(
+ reinterpret_cast<const char*>(vector_as_array(&json)), json.size());
+ scoped_ptr<base::Value> value = base::JSONReader::Read(json_string);
+ EXPECT_TRUE(value.get());
+ EXPECT_TRUE(value->IsType(base::Value::TYPE_DICTIONARY));
+
+ return scoped_ptr<base::DictionaryValue>(
+ static_cast<base::DictionaryValue*>(value.release()));
+}
+
+// Verifies the input dictionary contains the expected values. Exact matches are
+// required on the fields examined.
+::testing::AssertionResult VerifyJwk(
+ const scoped_ptr<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))
+ return ::testing::AssertionFailure() << "Missing 'kty'";
+ if (value_string != kty_expected)
+ return ::testing::AssertionFailure() << "Expected 'kty' to be "
+ << kty_expected << "but found "
+ << value_string;
+
+ // ---- alg
+ if (!dict->GetString("alg", &value_string))
+ return ::testing::AssertionFailure() << "Missing 'alg'";
+ if (value_string != alg_expected)
+ return ::testing::AssertionFailure() << "Expected 'alg' to be "
+ << alg_expected << " but found "
+ << value_string;
+
+ // ---- ext
+ // always expect ext == true in this case
+ bool 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))
+ return ::testing::AssertionFailure() << "Missing 'key_ops'";
+ blink::WebCryptoKeyUsageMask key_ops_mask = 0;
+ Status status =
+ GetWebCryptoUsagesFromJwkKeyOpsForTest(key_ops, &key_ops_mask);
+ if (status.IsError())
+ return ::testing::AssertionFailure() << "Failure extracting 'key_ops'";
+ if (key_ops_mask != use_mask_expected)
+ return ::testing::AssertionFailure()
+ << "Expected 'key_ops' mask to be " << use_mask_expected
+ << " but found " << key_ops_mask << " (" << value_string << ")";
+
+ return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySecretJwk(
+ const std::vector<uint8_t>& json,
+ const std::string& alg_expected,
+ const std::string& k_expected_hex,
+ blink::WebCryptoKeyUsageMask use_mask_expected) {
+ scoped_ptr<base::DictionaryValue> dict = GetJwkDictionary(json);
+ if (!dict.get() || dict->empty())
+ return ::testing::AssertionFailure() << "JSON parsing failed";
+
+ // ---- k
+ std::string value_string;
+ if (!dict->GetString("k", &value_string))
+ return ::testing::AssertionFailure() << "Missing 'k'";
+ std::string k_value;
+ if (!Base64DecodeUrlSafe(value_string, &k_value))
+ return ::testing::AssertionFailure() << "Base64DecodeUrlSafe(k) failed";
+ if (!base::LowerCaseEqualsASCII(
+ base::HexEncode(k_value.data(), k_value.size()),
+ k_expected_hex.c_str())) {
+ return ::testing::AssertionFailure() << "Expected 'k' to be "
+ << k_expected_hex
+ << " but found something different";
+ }
+
+ return VerifyJwk(dict, "oct", alg_expected, use_mask_expected);
+}
+
+::testing::AssertionResult VerifyPublicJwk(
+ const std::vector<uint8_t>& json,
+ const std::string& alg_expected,
+ const std::string& n_expected_hex,
+ const std::string& e_expected_hex,
+ blink::WebCryptoKeyUsageMask use_mask_expected) {
+ scoped_ptr<base::DictionaryValue> dict = GetJwkDictionary(json);
+ if (!dict.get() || dict->empty())
+ return ::testing::AssertionFailure() << "JSON parsing failed";
+
+ // ---- n
+ std::string value_string;
+ if (!dict->GetString("n", &value_string))
+ return ::testing::AssertionFailure() << "Missing 'n'";
+ std::string n_value;
+ if (!Base64DecodeUrlSafe(value_string, &n_value))
+ return ::testing::AssertionFailure() << "Base64DecodeUrlSafe(n) failed";
+ if (base::HexEncode(n_value.data(), n_value.size()) != n_expected_hex) {
+ return ::testing::AssertionFailure() << "'n' does not match the expected "
+ "value";
+ }
+ // TODO(padolph): LowerCaseEqualsASCII() does not work for above!
+
+ // ---- e
+ if (!dict->GetString("e", &value_string))
+ return ::testing::AssertionFailure() << "Missing 'e'";
+ std::string e_value;
+ if (!Base64DecodeUrlSafe(value_string, &e_value))
+ return ::testing::AssertionFailure() << "Base64DecodeUrlSafe(e) failed";
+ if (!base::LowerCaseEqualsASCII(
+ base::HexEncode(e_value.data(), e_value.size()),
+ e_expected_hex.c_str())) {
+ return ::testing::AssertionFailure() << "Expected 'e' to be "
+ << e_expected_hex
+ << " but found something different";
+ }
+
+ return VerifyJwk(dict, "RSA", alg_expected, use_mask_expected);
+}
+
+void ImportExportJwkSymmetricKey(
+ int key_len_bits,
+ const blink::WebCryptoAlgorithm& import_algorithm,
+ blink::WebCryptoKeyUsageMask usages,
+ const std::string& jwk_alg) {
+ std::vector<uint8_t> json;
+ std::string key_hex;
+
+ // Hardcoded pseudo-random bytes to use for keys of different lengths.
+ switch (key_len_bits) {
+ case 128:
+ key_hex = "3f1e7cd4f6f8543f6b1e16002e688623";
+ break;
+ case 256:
+ key_hex =
+ "bd08286b81a74783fd1ccf46b7e05af84ee25ae021210074159e0c4d9d907692";
+ break;
+ case 384:
+ key_hex =
+ "a22c5441c8b185602283d64c7221de1d0951e706bfc09539435ec0e0ed614e1d40"
+ "6623f2b31d31819fec30993380dd82";
+ break;
+ case 512:
+ key_hex =
+ "5834f639000d4cf82de124fbfd26fb88d463e99f839a76ba41ac88967c80a3f61e"
+ "1239a452e573dba0750e988152988576efd75b8d0229b7aca2ada2afd392ee";
+ break;
+ default:
+ FAIL() << "Unexpected key_len_bits" << key_len_bits;
+ }
+
+ // Import a raw key.
+ blink::WebCryptoKey key = ImportSecretKeyFromRaw(HexStringToBytes(key_hex),
+ import_algorithm, usages);
+
+ // Export the key in JWK format and validate.
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatJwk, key, &json));
+ EXPECT_TRUE(VerifySecretJwk(json, jwk_alg, key_hex, usages));
+
+ // Import the JWK-formatted key.
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(json),
+ import_algorithm, true, usages, &key));
+ EXPECT_TRUE(key.handle());
+ EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ EXPECT_EQ(import_algorithm.id(), key.algorithm().id());
+ EXPECT_EQ(true, key.extractable());
+ EXPECT_EQ(usages, key.usages());
+
+ // Export the key in raw format and compare to the original.
+ std::vector<uint8_t> key_raw_out;
+ ASSERT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_raw_out));
+ EXPECT_BYTES_EQ_HEX(key_hex, key_raw_out);
+}
+
+Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoKey* key) {
+ GenerateKeyResult result;
+ Status status = GenerateKey(algorithm, extractable, usages, &result);
+ if (status.IsError())
+ return status;
+
+ if (result.type() != GenerateKeyResult::TYPE_SECRET_KEY)
+ return Status::ErrorUnexpected();
+
+ *key = result.secret_key();
+
+ return Status::Success();
+}
+
+Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoKey* public_key,
+ blink::WebCryptoKey* private_key) {
+ GenerateKeyResult result;
+ Status status = GenerateKey(algorithm, extractable, usages, &result);
+ if (status.IsError())
+ return status;
+
+ if (result.type() != GenerateKeyResult::TYPE_PUBLIC_PRIVATE_KEY_PAIR)
+ return Status::ErrorUnexpected();
+
+ *public_key = result.public_key();
+ *private_key = result.private_key();
+
+ return Status::Success();
+}
+
+blink::WebCryptoKeyFormat GetKeyFormatFromJsonTestCase(
+ const base::DictionaryValue* test) {
+ std::string format;
+ EXPECT_TRUE(test->GetString("key_format", &format));
+ if (format == "jwk")
+ return blink::WebCryptoKeyFormatJwk;
+ else if (format == "pkcs8")
+ return blink::WebCryptoKeyFormatPkcs8;
+ else if (format == "spki")
+ return blink::WebCryptoKeyFormatSpki;
+ else if (format == "raw")
+ return blink::WebCryptoKeyFormatRaw;
+
+ ADD_FAILURE() << "Unrecognized key format: " << format;
+ return blink::WebCryptoKeyFormatRaw;
+}
+
+std::vector<uint8_t> GetKeyDataFromJsonTestCase(
+ const base::DictionaryValue* test,
+ blink::WebCryptoKeyFormat key_format) {
+ if (key_format == blink::WebCryptoKeyFormatJwk) {
+ const base::DictionaryValue* json;
+ EXPECT_TRUE(test->GetDictionary("key", &json));
+ return MakeJsonVector(*json);
+ }
+ return GetBytesFromHexString(test, "key");
+}
+
+blink::WebCryptoNamedCurve GetCurveNameFromDictionary(
+ const base::DictionaryValue* dict) {
+ std::string curve_str;
+ if (!dict->GetString("crv", &curve_str)) {
+ ADD_FAILURE() << "Missing crv parameter";
+ return blink::WebCryptoNamedCurveP384;
+ }
+
+ if (curve_str == "P-256")
+ return blink::WebCryptoNamedCurveP256;
+ if (curve_str == "P-384")
+ return blink::WebCryptoNamedCurveP384;
+ if (curve_str == "P-521")
+ return blink::WebCryptoNamedCurveP521;
+ else
+ ADD_FAILURE() << "Unrecognized curve name: " << curve_str;
+
+ return blink::WebCryptoNamedCurveP384;
+}
+
+blink::WebCryptoAlgorithm CreateHmacImportAlgorithm(
+ blink::WebCryptoAlgorithmId hash_id,
+ unsigned int length_bits) {
+ DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdHmac,
+ new blink::WebCryptoHmacImportParams(CreateAlgorithm(hash_id), true,
+ length_bits));
+}
+
+blink::WebCryptoAlgorithm CreateHmacImportAlgorithmNoLength(
+ blink::WebCryptoAlgorithmId hash_id) {
+ DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdHmac,
+ new blink::WebCryptoHmacImportParams(CreateAlgorithm(hash_id), false, 0));
+}
+
+blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(id, nullptr);
+}
+
+blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmId id,
+ blink::WebCryptoAlgorithmId hash_id) {
+ DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ id, new blink::WebCryptoRsaHashedImportParams(CreateAlgorithm(hash_id)));
+}
+
+blink::WebCryptoAlgorithm CreateEcImportAlgorithm(
+ blink::WebCryptoAlgorithmId id,
+ blink::WebCryptoNamedCurve named_curve) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ id, new blink::WebCryptoEcKeyImportParams(named_curve));
+}
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/test_helpers.h b/chromium/components/webcrypto/algorithms/test_helpers.h
new file mode 100644
index 00000000000..3cc87d22e19
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/test_helpers.h
@@ -0,0 +1,236 @@
+// 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_WEBCRYPTO_ALGORITHMS_TEST_HELPERS_H_
+#define COMPONENTS_WEBCRYPTO_ALGORITHMS_TEST_HELPERS_H_
+
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
+#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+
+#define EXPECT_BYTES_EQ(expected, actual) \
+ EXPECT_EQ(CryptoData(expected), CryptoData(actual))
+
+#define EXPECT_BYTES_EQ_HEX(expected_hex, actual_bytes) \
+ EXPECT_BYTES_EQ(HexStringToBytes(expected_hex), actual_bytes)
+
+namespace base {
+class DictionaryValue;
+class ListValue;
+class Value;
+}
+
+namespace blink {
+class WebCryptoAlgorithm;
+}
+
+namespace webcrypto {
+
+// Base class for WebCrypto tests. All WebCrypto tests must derive from this
+// to ensure that Blink has been properly initialized. In particular,
+// the WebCrypto tests use blink::WebCryptoAlgorithm, which in turn relies on
+// PartitionAlloc.
+class WebCryptoTestBase : public testing::Test {
+ protected:
+ static void SetUpTestCase();
+};
+
+class Status;
+class CryptoData;
+
+// These functions are used by GTEST to support EXPECT_EQ() for
+// webcrypto::Status and webcrypto::CryptoData
+
+void PrintTo(const Status& status, ::std::ostream* os);
+bool operator==(const Status& a, const Status& b);
+bool operator!=(const Status& a, const Status& b);
+
+void PrintTo(const CryptoData& data, ::std::ostream* os);
+bool operator==(const CryptoData& a, const CryptoData& b);
+bool operator!=(const CryptoData& a, const CryptoData& b);
+
+// Gives a human-readable description of |status| and any error it represents.
+std::string StatusToString(const Status& status);
+
+blink::WebCryptoAlgorithm CreateRsaHashedKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmId algorithm_id,
+ const blink::WebCryptoAlgorithmId hash_id,
+ unsigned int modulus_length,
+ const std::vector<uint8_t>& public_exponent);
+
+// Returns a slightly modified version of the input vector.
+//
+// - For non-empty inputs a single bit is inverted.
+// - For empty inputs, a byte is added.
+std::vector<uint8_t> Corrupted(const std::vector<uint8_t>& input);
+
+std::vector<uint8_t> HexStringToBytes(const std::string& hex);
+
+std::vector<uint8_t> MakeJsonVector(const std::string& json_string);
+std::vector<uint8_t> MakeJsonVector(const base::DictionaryValue& dict);
+
+// ----------------------------------------------------------------
+// Helpers for working with JSON data files for test expectations.
+// ----------------------------------------------------------------
+
+// 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,
+ scoped_ptr<base::Value>* value);
+// Same as ReadJsonTestFile(), but returns the value as a List.
+::testing::AssertionResult ReadJsonTestFileToList(
+ const char* test_file_name,
+ scoped_ptr<base::ListValue>* list);
+// Same as ReadJsonTestFile(), but returns the value as a Dictionary.
+::testing::AssertionResult ReadJsonTestFileToDictionary(
+ const char* test_file_name,
+ scoped_ptr<base::DictionaryValue>* dict);
+
+// Reads a string property from the dictionary with path |property_name|
+// (which can include periods for nested dictionaries). Interprets the
+// string as a hex encoded string and converts it to a bytes list.
+//
+// Returns empty vector on failure.
+std::vector<uint8_t> GetBytesFromHexString(const base::DictionaryValue* dict,
+ const std::string& property_name);
+
+// Reads a string property with path "property_name" and converts it to a
+// WebCryptoAlgorith. Returns null algorithm on failure.
+blink::WebCryptoAlgorithm GetDigestAlgorithm(const base::DictionaryValue* dict,
+ const char* property_name);
+
+// Returns true if any of the vectors in the input list have identical content.
+bool CopiesExist(const std::vector<std::vector<uint8_t>>& bufs);
+
+blink::WebCryptoAlgorithm CreateAesKeyGenAlgorithm(
+ blink::WebCryptoAlgorithmId aes_alg_id,
+ unsigned short 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
+// NIST test vectors at
+// ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt
+extern const unsigned int kModulusLengthBits;
+extern const char* const kPublicKeySpkiDerHex;
+extern const char* const kPrivateKeyPkcs8DerHex;
+
+// The modulus and exponent (in hex) of kPublicKeySpkiDerHex
+extern const char* const kPublicKeyModulusHex;
+extern const char* const kPublicKeyExponentHex;
+
+blink::WebCryptoKey ImportSecretKeyFromRaw(
+ const std::vector<uint8_t>& key_raw,
+ const blink::WebCryptoAlgorithm& algorithm,
+ blink::WebCryptoKeyUsageMask usage);
+
+void ImportRsaKeyPair(const std::vector<uint8_t>& spki_der,
+ const std::vector<uint8_t>& pkcs8_der,
+ const blink::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask public_key_usages,
+ blink::WebCryptoKeyUsageMask private_key_usages,
+ blink::WebCryptoKey* public_key,
+ blink::WebCryptoKey* private_key);
+
+Status ImportKeyJwkFromDict(const base::DictionaryValue& dict,
+ const blink::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoKey* key);
+
+// Parses a vector of JSON into a dictionary.
+scoped_ptr<base::DictionaryValue> GetJwkDictionary(
+ const std::vector<uint8_t>& json);
+
+// Verifies the input dictionary contains the expected values. Exact matches are
+// required on the fields examined.
+::testing::AssertionResult VerifyJwk(
+ const scoped_ptr<base::DictionaryValue>& dict,
+ const std::string& kty_expected,
+ const std::string& alg_expected,
+ blink::WebCryptoKeyUsageMask use_mask_expected);
+
+::testing::AssertionResult VerifySecretJwk(
+ const std::vector<uint8_t>& json,
+ const std::string& alg_expected,
+ const std::string& k_expected_hex,
+ blink::WebCryptoKeyUsageMask use_mask_expected);
+
+// Verifies that the JSON in the input vector contains the provided
+// expected values. Exact matches are required on the fields examined.
+::testing::AssertionResult VerifyPublicJwk(
+ const std::vector<uint8_t>& json,
+ const std::string& alg_expected,
+ const std::string& n_expected_hex,
+ const std::string& e_expected_hex,
+ blink::WebCryptoKeyUsageMask use_mask_expected);
+
+// Helper that tests importing ane exporting of symmetric keys as JWK.
+void ImportExportJwkSymmetricKey(
+ int key_len_bits,
+ const blink::WebCryptoAlgorithm& import_algorithm,
+ blink::WebCryptoKeyUsageMask usages,
+ const std::string& jwk_alg);
+
+// Wrappers around GenerateKey() which expect the result to be either a secret
+// key or a public/private keypair. If the result does not match the
+// expectation, then it fails with Status::ErrorUnexpected().
+Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoKey* key);
+Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoKey* public_key,
+ blink::WebCryptoKey* private_key);
+
+// Reads a key format string as used in some JSON test files and converts it to
+// a WebCryptoKeyFormat.
+blink::WebCryptoKeyFormat GetKeyFormatFromJsonTestCase(
+ const base::DictionaryValue* test);
+
+// Extracts the key data bytes from |test| as used insome JSON test files.
+std::vector<uint8_t> GetKeyDataFromJsonTestCase(
+ const base::DictionaryValue* test,
+ blink::WebCryptoKeyFormat key_format);
+
+// Reads the "crv" string from a JSON test case and returns it as a
+// WebCryptoNamedCurve.
+blink::WebCryptoNamedCurve GetCurveNameFromDictionary(
+ const base::DictionaryValue* dict);
+
+// Creates an HMAC import algorithm whose inner hash algorithm is determined by
+// the specified algorithm ID. It is an error to call this method with a hash
+// algorithm that is not SHA*.
+blink::WebCryptoAlgorithm CreateHmacImportAlgorithm(
+ blink::WebCryptoAlgorithmId hash_id,
+ unsigned int length_bits);
+
+// Same as above but without specifying a length.
+blink::WebCryptoAlgorithm CreateHmacImportAlgorithmNoLength(
+ blink::WebCryptoAlgorithmId hash_id);
+
+// Creates a WebCryptoAlgorithm without any parameters.
+blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id);
+
+// Creates an import algorithm for RSA algorithms that take a hash.
+// It is an error to call this with a hash_id that is not a SHA*.
+blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmId id,
+ blink::WebCryptoAlgorithmId hash_id);
+
+// Creates an import algorithm for EC keys.
+blink::WebCryptoAlgorithm CreateEcImportAlgorithm(
+ blink::WebCryptoAlgorithmId id,
+ blink::WebCryptoNamedCurve named_curve);
+
+} // namespace webcrypto
+
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_TEST_HELPERS_H_
diff --git a/chromium/components/webcrypto/algorithms/util.cc b/chromium/components/webcrypto/algorithms/util.cc
new file mode 100644
index 00000000000..43e728cd61d
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/util.cc
@@ -0,0 +1,127 @@
+// 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/webcrypto/algorithms/util.h"
+
+#include <openssl/aead.h>
+#include <openssl/bn.h>
+#include <openssl/digest.h>
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+#include "crypto/openssl_util.h"
+#include "crypto/scoped_openssl_types.h"
+
+namespace webcrypto {
+
+const EVP_MD* GetDigest(const blink::WebCryptoAlgorithm& hash_algorithm) {
+ return GetDigest(hash_algorithm.id());
+}
+
+const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id) {
+ switch (id) {
+ case blink::WebCryptoAlgorithmIdSha1:
+ return EVP_sha1();
+ case blink::WebCryptoAlgorithmIdSha256:
+ return EVP_sha256();
+ case blink::WebCryptoAlgorithmIdSha384:
+ return EVP_sha384();
+ case blink::WebCryptoAlgorithmIdSha512:
+ return EVP_sha512();
+ default:
+ return NULL;
+ }
+}
+
+void TruncateToBitLength(size_t length_bits, std::vector<uint8_t>* bytes) {
+ size_t length_bytes = NumBitsToBytes(length_bits);
+
+ if (bytes->size() != length_bytes) {
+ CHECK_LT(length_bytes, bytes->size());
+ bytes->resize(length_bytes);
+ }
+
+ size_t remainder_bits = length_bits % 8;
+
+ // Zero any "unused bits" in the final byte.
+ if (remainder_bits)
+ (*bytes)[bytes->size() - 1] &= ~((0xFF) >> remainder_bits);
+}
+
+Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages,
+ EmptyUsagePolicy empty_usage_policy) {
+ if (actual_usages == 0 &&
+ empty_usage_policy == EmptyUsagePolicy::REJECT_EMPTY) {
+ return Status::ErrorCreateKeyEmptyUsages();
+ }
+
+ if (!ContainsKeyUsages(all_possible_usages, actual_usages))
+ return Status::ErrorCreateKeyBadUsages();
+ return Status::Success();
+}
+
+bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
+ blink::WebCryptoKeyUsageMask b) {
+ return (a & b) == b;
+}
+
+BIGNUM* CreateBIGNUM(const std::string& n) {
+ return BN_bin2bn(reinterpret_cast<const uint8_t*>(n.data()), n.size(), NULL);
+}
+
+Status AeadEncryptDecrypt(EncryptOrDecrypt mode,
+ const std::vector<uint8_t>& raw_key,
+ const CryptoData& data,
+ unsigned int tag_length_bytes,
+ const CryptoData& iv,
+ const CryptoData& additional_data,
+ const EVP_AEAD* aead_alg,
+ std::vector<uint8_t>* buffer) {
+ crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+ EVP_AEAD_CTX ctx;
+
+ if (!aead_alg)
+ return Status::ErrorUnexpected();
+
+ if (!EVP_AEAD_CTX_init(&ctx, aead_alg, vector_as_array(&raw_key),
+ raw_key.size(), tag_length_bytes, NULL)) {
+ return Status::OperationError();
+ }
+
+ crypto::ScopedOpenSSL<EVP_AEAD_CTX, EVP_AEAD_CTX_cleanup> ctx_cleanup(&ctx);
+
+ size_t len;
+ int ok;
+
+ if (mode == DECRYPT) {
+ if (data.byte_length() < tag_length_bytes)
+ return Status::ErrorDataTooSmall();
+
+ buffer->resize(data.byte_length() - tag_length_bytes);
+
+ ok = EVP_AEAD_CTX_open(&ctx, vector_as_array(buffer), &len, buffer->size(),
+ iv.bytes(), iv.byte_length(), data.bytes(),
+ data.byte_length(), additional_data.bytes(),
+ additional_data.byte_length());
+ } else {
+ // No need to check for unsigned integer overflow here (seal fails if
+ // the output buffer is too small).
+ buffer->resize(data.byte_length() + EVP_AEAD_max_overhead(aead_alg));
+
+ ok = EVP_AEAD_CTX_seal(&ctx, vector_as_array(buffer), &len, buffer->size(),
+ iv.bytes(), iv.byte_length(), data.bytes(),
+ data.byte_length(), additional_data.bytes(),
+ additional_data.byte_length());
+ }
+
+ if (!ok)
+ return Status::OperationError();
+ buffer->resize(len);
+ return Status::Success();
+}
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/algorithms/util.h b/chromium/components/webcrypto/algorithms/util.h
new file mode 100644
index 00000000000..8fa292651f0
--- /dev/null
+++ b/chromium/components/webcrypto/algorithms/util.h
@@ -0,0 +1,96 @@
+// 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_WEBCRYPTO_ALGORITHMS_UTIL_H_
+#define COMPONENTS_WEBCRYPTO_ALGORITHMS_UTIL_H_
+
+#include <string>
+#include <vector>
+
+#include <openssl/base.h>
+
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
+#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+
+// This file contains miscellaneous helpers that don't belong in any of the
+// other *_util.h
+
+namespace webcrypto {
+
+class CryptoData;
+class GenerateKeyResult;
+class Status;
+
+// Returns the EVP_MD that corresponds with |hash_algorithm|, or nullptr on
+// failure.
+const EVP_MD* GetDigest(const blink::WebCryptoAlgorithm& hash_algorithm);
+
+// Returns the EVP_MD that corresponds with |id|, or nullptr on failure.
+const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id);
+
+// Truncates an octet string to a particular bit length. This is accomplished by
+// resizing to the closest byte length, and then zero-ing the unused
+// least-significant bits of the final byte.
+//
+// It is an error to call this function with a bit length that is larger than
+// that of |bytes|.
+//
+// TODO(eroman): This operation is not yet defined by the WebCrypto spec,
+// however this is a reasonable interpretation:
+// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27402
+void TruncateToBitLength(size_t length_bits, std::vector<uint8_t>* bytes);
+
+// Rounds a bit count (up) to the nearest byte count.
+//
+// This is mathematically equivalent to (x + 7) / 8, however has no
+// possibility of integer overflow.
+template <typename T>
+T NumBitsToBytes(T x) {
+ return (x / 8) + (7 + (x % 8)) / 8;
+}
+
+enum class EmptyUsagePolicy {
+ // Allow keys to have empty usages.
+ ALLOW_EMPTY,
+
+ // Do not allow keys to have empty usages.
+ REJECT_EMPTY,
+};
+
+// Verifies whether a key can be created using |actual_usages| when the
+// algorithm supports |all_possible_usages|.
+Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages,
+ EmptyUsagePolicy empty_usage_policy);
+
+// TODO(eroman): This doesn't really belong in this file. Move it into Blink
+// instead.
+//
+// Returns true if the set bits in b make up a subset of the set bits in a.
+bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
+ blink::WebCryptoKeyUsageMask b);
+
+// Allocates a new BIGNUM given a std::string big-endian representation.
+BIGNUM* CreateBIGNUM(const std::string& n);
+
+// The values of these constants correspond with the "enc" parameter of
+// EVP_CipherInit_ex(), do not change.
+enum EncryptOrDecrypt { DECRYPT = 0, ENCRYPT = 1 };
+
+// Does either encryption or decryption for an AEAD algorithm.
+// * |mode| controls whether encryption or decryption is done
+// * |aead_alg| the algorithm (for instance AES-GCM)
+// * |buffer| where the ciphertext or plaintext is written to.
+Status AeadEncryptDecrypt(EncryptOrDecrypt mode,
+ const std::vector<uint8_t>& raw_key,
+ const CryptoData& data,
+ unsigned int tag_length_bytes,
+ const CryptoData& iv,
+ const CryptoData& additional_data,
+ const EVP_AEAD* aead_alg,
+ std::vector<uint8_t>* buffer);
+
+} // namespace webcrypto
+
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_UTIL_H_
diff --git a/chromium/components/webcrypto/blink_key_handle.cc b/chromium/components/webcrypto/blink_key_handle.cc
new file mode 100644
index 00000000000..6b8c1f4cdba
--- /dev/null
+++ b/chromium/components/webcrypto/blink_key_handle.cc
@@ -0,0 +1,111 @@
+// 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/webcrypto/blink_key_handle.h"
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+
+namespace webcrypto {
+
+namespace {
+
+class SymKey;
+class AsymKey;
+
+// Base class for wrapping OpenSSL keys in a type that can be passed to
+// Blink (blink::WebCryptoKeyHandle).
+//
+// In addition to the key's internal OpenSSL representation (EVP_PKEY or just
+// raw bytes), each key maintains a copy of its serialized form in either
+// 'raw', 'pkcs8', or 'spki' format. This is to allow structured cloning of
+// keys to be done synchronously from the target Blink thread, without having to
+// lock access to the key throughout the code.
+class Key : public blink::WebCryptoKeyHandle {
+ public:
+ explicit Key(const CryptoData& serialized_key_data)
+ : serialized_key_data_(
+ serialized_key_data.bytes(),
+ serialized_key_data.bytes() + serialized_key_data.byte_length()) {}
+
+ ~Key() override {}
+
+ // Helpers to add some safety to casting.
+ virtual SymKey* AsSymKey() { return nullptr; }
+ virtual AsymKey* AsAsymKey() { return nullptr; }
+
+ const std::vector<uint8_t>& serialized_key_data() const {
+ return serialized_key_data_;
+ }
+
+ private:
+ const std::vector<uint8_t> serialized_key_data_;
+};
+
+class SymKey : public Key {
+ public:
+ explicit SymKey(const CryptoData& raw_key_data) : Key(raw_key_data) {}
+
+ SymKey* AsSymKey() override { return this; }
+
+ const std::vector<uint8_t>& raw_key_data() const {
+ return serialized_key_data();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SymKey);
+};
+
+class AsymKey : public Key {
+ public:
+ AsymKey(crypto::ScopedEVP_PKEY pkey,
+ const std::vector<uint8_t>& serialized_key_data)
+ : Key(CryptoData(serialized_key_data)), pkey_(pkey.Pass()) {}
+
+ AsymKey* AsAsymKey() override { return this; }
+
+ EVP_PKEY* pkey() { return pkey_.get(); }
+
+ private:
+ crypto::ScopedEVP_PKEY pkey_;
+
+ DISALLOW_COPY_AND_ASSIGN(AsymKey);
+};
+
+Key* GetKey(const blink::WebCryptoKey& key) {
+ return reinterpret_cast<Key*>(key.handle());
+}
+
+} // namespace
+
+const std::vector<uint8_t>& GetSymmetricKeyData(
+ const blink::WebCryptoKey& key) {
+ DCHECK_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ return GetKey(key)->AsSymKey()->raw_key_data();
+}
+
+EVP_PKEY* GetEVP_PKEY(const blink::WebCryptoKey& key) {
+ DCHECK_NE(blink::WebCryptoKeyTypeSecret, key.type());
+ return GetKey(key)->AsAsymKey()->pkey();
+}
+
+const std::vector<uint8_t>& GetSerializedKeyData(
+ const blink::WebCryptoKey& key) {
+ return GetKey(key)->serialized_key_data();
+}
+
+blink::WebCryptoKeyHandle* CreateSymmetricKeyHandle(
+ const CryptoData& key_bytes) {
+ return new SymKey(key_bytes);
+}
+
+blink::WebCryptoKeyHandle* CreateAsymmetricKeyHandle(
+ crypto::ScopedEVP_PKEY pkey,
+ const std::vector<uint8_t>& serialized_key_data) {
+ return new AsymKey(pkey.Pass(), serialized_key_data);
+}
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/blink_key_handle.h b/chromium/components/webcrypto/blink_key_handle.h
new file mode 100644
index 00000000000..049657c6195
--- /dev/null
+++ b/chromium/components/webcrypto/blink_key_handle.h
@@ -0,0 +1,61 @@
+// 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_WEBCRYPTO_BLINK_KEY_HANDLE_H_
+#define COMPONENTS_WEBCRYPTO_BLINK_KEY_HANDLE_H_
+
+#include <openssl/base.h>
+#include <stdint.h>
+
+#include <vector>
+
+#include "crypto/scoped_openssl_types.h"
+#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+
+// Blink keys (blink::WebCryptoKey) have an associated key handle
+// (blink::WebCryptoKeyHandle) used to store custom data. This is where the
+// underlying EVP_PKEY is stored for asymmetric keys, or an std::vector
+// containing the bytes for symmetric keys.
+//
+// This file contains helpers for creating the key handles, and extracting
+// properties from it.
+
+namespace webcrypto {
+
+class CryptoData;
+
+// Returns a reference to the symmetric key data wrapped by the given Blink
+// key. The returned reference is owned by |key|. This function must only be
+// called on secret keys (HMAC, AES, etc).
+const std::vector<uint8_t>& GetSymmetricKeyData(const blink::WebCryptoKey& key);
+
+// Returns the EVP_PKEY* wrapped by the given Blink key. The returned pointer
+// is owned by |key|. This function must only be called on asymmetric keys
+// (RSA, EC, etc).
+EVP_PKEY* GetEVP_PKEY(const blink::WebCryptoKey& key);
+
+// Returns a reference to the serialized key data. This reference is owned by
+// |key|. This function can be called for any key type.
+const std::vector<uint8_t>& GetSerializedKeyData(
+ const blink::WebCryptoKey& key);
+
+// Creates a symmetric key handle that can be passed to Blink. The caller takes
+// ownership of the returned pointer.
+blink::WebCryptoKeyHandle* CreateSymmetricKeyHandle(
+ const CryptoData& key_bytes);
+
+// Creates an asymmetric key handle that can be passed to Blink. The caller
+// takes
+// ownership of the returned pointer.
+//
+// TODO(eroman): This should _move_ input serialized_key_data rather than
+// create a copy, since all the callers are passing in vectors that are later
+// thrown away anyway.
+blink::WebCryptoKeyHandle* CreateAsymmetricKeyHandle(
+ crypto::ScopedEVP_PKEY pkey,
+ const std::vector<uint8_t>& serialized_key_data);
+
+} // namespace webcrypto
+
+#endif // COMPONENTS_WEBCRYPTO_BLINK_KEY_HANDLE_H_
diff --git a/chromium/components/webcrypto/jwk.cc b/chromium/components/webcrypto/jwk.cc
index 98a8b1b85f4..023ea826bee 100644
--- a/chromium/components/webcrypto/jwk.cc
+++ b/chromium/components/webcrypto/jwk.cc
@@ -12,14 +12,9 @@
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
+#include "components/webcrypto/algorithms/util.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-
-// TODO(eroman): The algorithm-specific logic in this file for AES and RSA
-// should be moved into the corresponding AlgorithmImplementation file. It
-// exists in this file to avoid duplication between OpenSSL and NSS
-// implementations.
// JSON Web Key Format (JWK) is defined by:
// http://tools.ietf.org/html/draft-ietf-jose-json-web-key
@@ -373,213 +368,6 @@ void JwkWriter::ToJson(std::vector<uint8_t>* utf8_bytes) const {
utf8_bytes->assign(json.begin(), json.end());
}
-Status ReadSecretKeyNoExpectedAlg(const CryptoData& key_data,
- bool expected_extractable,
- blink::WebCryptoKeyUsageMask expected_usages,
- std::vector<uint8_t>* raw_key_data,
- JwkReader* jwk) {
- Status status = jwk->Init(key_data, expected_extractable, expected_usages,
- "oct", std::string());
- if (status.IsError())
- return status;
-
- std::string jwk_k_value;
- status = jwk->GetBytes("k", &jwk_k_value);
- if (status.IsError())
- return status;
- raw_key_data->assign(jwk_k_value.begin(), jwk_k_value.end());
-
- return Status::Success();
-}
-
-void WriteSecretKeyJwk(const CryptoData& raw_key_data,
- const std::string& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- std::vector<uint8_t>* jwk_key_data) {
- JwkWriter writer(algorithm, extractable, usages, "oct");
- writer.SetBytes("k", raw_key_data);
- writer.ToJson(jwk_key_data);
-}
-
-Status ReadSecretKeyJwk(const CryptoData& key_data,
- const std::string& expected_alg,
- bool expected_extractable,
- blink::WebCryptoKeyUsageMask expected_usages,
- std::vector<uint8_t>* raw_key_data) {
- JwkReader jwk;
- Status status = ReadSecretKeyNoExpectedAlg(
- key_data, expected_extractable, expected_usages, raw_key_data, &jwk);
- if (status.IsError())
- return status;
- return jwk.VerifyAlg(expected_alg);
-}
-
-std::string MakeJwkAesAlgorithmName(const std::string& suffix,
- size_t keylen_bytes) {
- if (keylen_bytes == 16)
- return std::string("A128") + suffix;
- if (keylen_bytes == 24)
- return std::string("A192") + suffix;
- if (keylen_bytes == 32)
- return std::string("A256") + suffix;
- return std::string();
-}
-
-Status ReadAesSecretKeyJwk(const CryptoData& key_data,
- const std::string& algorithm_name_suffix,
- bool expected_extractable,
- blink::WebCryptoKeyUsageMask expected_usages,
- std::vector<uint8_t>* raw_key_data) {
- JwkReader jwk;
- Status status = ReadSecretKeyNoExpectedAlg(
- key_data, expected_extractable, expected_usages, raw_key_data, &jwk);
- if (status.IsError())
- return status;
-
- bool has_jwk_alg;
- std::string jwk_alg;
- status = jwk.GetAlg(&jwk_alg, &has_jwk_alg);
- if (status.IsError())
- return status;
-
- if (has_jwk_alg) {
- std::string expected_algorithm_name =
- MakeJwkAesAlgorithmName(algorithm_name_suffix, raw_key_data->size());
-
- if (jwk_alg != expected_algorithm_name) {
- // Give a different error message if the key length was wrong.
- if (jwk_alg == MakeJwkAesAlgorithmName(algorithm_name_suffix, 16) ||
- jwk_alg == MakeJwkAesAlgorithmName(algorithm_name_suffix, 24) ||
- jwk_alg == MakeJwkAesAlgorithmName(algorithm_name_suffix, 32)) {
- return Status::ErrorJwkIncorrectKeyLength();
- }
- return Status::ErrorJwkAlgorithmInconsistent();
- }
- }
-
- return Status::Success();
-}
-
-// Writes an RSA public key to a JWK dictionary
-void WriteRsaPublicKeyJwk(const CryptoData& n,
- const CryptoData& e,
- const std::string& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- std::vector<uint8_t>* jwk_key_data) {
- JwkWriter writer(algorithm, extractable, usages, "RSA");
- writer.SetBytes("n", n);
- writer.SetBytes("e", e);
- writer.ToJson(jwk_key_data);
-}
-
-// Writes an RSA private key to a JWK dictionary
-void WriteRsaPrivateKeyJwk(const CryptoData& n,
- const CryptoData& e,
- const CryptoData& d,
- const CryptoData& p,
- const CryptoData& q,
- const CryptoData& dp,
- const CryptoData& dq,
- const CryptoData& qi,
- const std::string& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- std::vector<uint8_t>* jwk_key_data) {
- JwkWriter writer(algorithm, extractable, usages, "RSA");
-
- writer.SetBytes("n", n);
- writer.SetBytes("e", e);
- writer.SetBytes("d", d);
- // Although these are "optional" in the JWA, WebCrypto spec requires them to
- // be emitted.
- writer.SetBytes("p", p);
- writer.SetBytes("q", q);
- writer.SetBytes("dp", dp);
- writer.SetBytes("dq", dq);
- writer.SetBytes("qi", qi);
- writer.ToJson(jwk_key_data);
-}
-
-JwkRsaInfo::JwkRsaInfo() : is_private_key(false) {
-}
-
-JwkRsaInfo::~JwkRsaInfo() {
-}
-
-Status ReadRsaKeyJwk(const CryptoData& key_data,
- const std::string& expected_alg,
- bool expected_extractable,
- blink::WebCryptoKeyUsageMask expected_usages,
- JwkRsaInfo* result) {
- JwkReader jwk;
- Status status = jwk.Init(key_data, expected_extractable, expected_usages,
- "RSA", expected_alg);
- if (status.IsError())
- return status;
-
- // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry
- // in the JWK, while an RSA private key must have those, plus at least a "d"
- // (private exponent) entry.
- // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
- // section 6.3.
- status = jwk.GetBigInteger("n", &result->n);
- if (status.IsError())
- return status;
- status = jwk.GetBigInteger("e", &result->e);
- if (status.IsError())
- return status;
-
- result->is_private_key = jwk.HasMember("d");
- if (!result->is_private_key)
- return Status::Success();
-
- status = jwk.GetBigInteger("d", &result->d);
- if (status.IsError())
- return status;
-
- // The "p", "q", "dp", "dq", and "qi" properties are optional in the JWA
- // spec. However they are required by Chromium's WebCrypto implementation.
-
- status = jwk.GetBigInteger("p", &result->p);
- if (status.IsError())
- return status;
-
- status = jwk.GetBigInteger("q", &result->q);
- if (status.IsError())
- return status;
-
- status = jwk.GetBigInteger("dp", &result->dp);
- if (status.IsError())
- return status;
-
- status = jwk.GetBigInteger("dq", &result->dq);
- if (status.IsError())
- return status;
-
- status = jwk.GetBigInteger("qi", &result->qi);
- if (status.IsError())
- return status;
-
- return Status::Success();
-}
-
-const char* GetJwkHmacAlgorithmName(blink::WebCryptoAlgorithmId hash) {
- switch (hash) {
- case blink::WebCryptoAlgorithmIdSha1:
- return "HS1";
- case blink::WebCryptoAlgorithmIdSha256:
- return "HS256";
- case blink::WebCryptoAlgorithmIdSha384:
- return "HS384";
- case blink::WebCryptoAlgorithmIdSha512:
- return "HS512";
- default:
- return NULL;
- }
-}
-
bool Base64DecodeUrlSafe(const std::string& input, std::string* output) {
// The JSON web signature spec specifically says that padding is omitted.
if (input.find_first_of("+/=") != std::string::npos)
diff --git a/chromium/components/webcrypto/jwk.h b/chromium/components/webcrypto/jwk.h
index 5ab62feef1d..411a986e106 100644
--- a/chromium/components/webcrypto/jwk.h
+++ b/chromium/components/webcrypto/jwk.h
@@ -126,106 +126,6 @@ class JwkWriter {
base::DictionaryValue dict_;
};
-// Writes a JWK-formatted symmetric key to |jwk_key_data|.
-// * raw_key_data: The actual key data
-// * algorithm: The JWK algorithm name (i.e. "alg")
-// * extractable: The JWK extractability (i.e. "ext")
-// * usages: The JWK usages (i.e. "key_ops")
-void WriteSecretKeyJwk(const CryptoData& raw_key_data,
- const std::string& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- std::vector<uint8_t>* jwk_key_data);
-
-// Parses a UTF-8 encoded JWK (key_data), and extracts the key material to
-// |*raw_key_data|. Returns Status::Success() on success, otherwise an error.
-// In order for this to succeed:
-// * expected_alg must match the JWK's "alg", if present.
-// * expected_extractable must be consistent with the JWK's "ext", if
-// present.
-// * expected_usages must be a subset of the JWK's "key_ops" if present.
-Status ReadSecretKeyJwk(const CryptoData& key_data,
- const std::string& expected_alg,
- bool expected_extractable,
- blink::WebCryptoKeyUsageMask expected_usages,
- std::vector<uint8_t>* raw_key_data);
-
-// Creates an AES algorithm name for the given key size (in bytes). For
-// instance "A128CBC" is the result of suffix="CBC", keylen_bytes=16.
-std::string MakeJwkAesAlgorithmName(const std::string& suffix,
- size_t keylen_bytes);
-
-// This is very similar to ReadSecretKeyJwk(), except instead of specifying an
-// absolute "expected_alg", the suffix for an AES algorithm name is given
-// (See MakeJwkAesAlgorithmName() for an explanation of what the suffix is).
-//
-// This is because the algorithm name for AES keys is dependent on the length
-// of the key. This function expects key lengths to be either 128, 192, or 256
-// bits.
-Status ReadAesSecretKeyJwk(const CryptoData& key_data,
- const std::string& algorithm_name_suffix,
- bool expected_extractable,
- blink::WebCryptoKeyUsageMask expected_usages,
- std::vector<uint8_t>* raw_key_data);
-
-// Writes a JWK-formated RSA public key and saves the result to
-// |*jwk_key_data|.
-void WriteRsaPublicKeyJwk(const CryptoData& n,
- const CryptoData& e,
- const std::string& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- std::vector<uint8_t>* jwk_key_data);
-
-// Writes a JWK-formated RSA private key and saves the result to
-// |*jwk_key_data|.
-void WriteRsaPrivateKeyJwk(const CryptoData& n,
- const CryptoData& e,
- const CryptoData& d,
- const CryptoData& p,
- const CryptoData& q,
- const CryptoData& dp,
- const CryptoData& dq,
- const CryptoData& qi,
- const std::string& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- std::vector<uint8_t>* jwk_key_data);
-
-// Describes the RSA components for a parsed key. The names of the properties
-// correspond with those from the JWK spec. Note that Chromium's WebCrypto
-// implementation does not support multi-primes, so there is no parsed field
-// for othinfo.
-struct JwkRsaInfo {
- JwkRsaInfo();
- ~JwkRsaInfo();
-
- bool is_private_key;
- std::string n;
- std::string e;
- std::string d;
- std::string p;
- std::string q;
- std::string dp;
- std::string dq;
- std::string qi;
-};
-
-// Parses a UTF-8 encoded JWK (key_data), and extracts the RSA components to
-// |*result|. Returns Status::Success() on success, otherwise an error.
-// In order for this to succeed:
-// * expected_alg must match the JWK's "alg", if present.
-// * expected_extractable must be consistent with the JWK's "ext", if
-// present.
-// * expected_usages must be a subset of the JWK's "key_ops" if present.
-Status ReadRsaKeyJwk(const CryptoData& key_data,
- const std::string& expected_alg,
- bool expected_extractable,
- blink::WebCryptoKeyUsageMask expected_usages,
- JwkRsaInfo* result);
-
-const char* GetJwkHmacAlgorithmName(blink::WebCryptoAlgorithmId hash);
-
// This decodes JWK's flavor of base64 encoding, as described by:
// https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-36#section-2
//
diff --git a/chromium/components/webcrypto/nss/aes_algorithm_nss.cc b/chromium/components/webcrypto/nss/aes_algorithm_nss.cc
deleted file mode 100644
index d09f5eecbec..00000000000
--- a/chromium/components/webcrypto/nss/aes_algorithm_nss.cc
+++ /dev/null
@@ -1,141 +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/webcrypto/nss/aes_algorithm_nss.h"
-
-#include "base/logging.h"
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/nss/key_nss.h"
-#include "components/webcrypto/nss/sym_key_nss.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
-
-namespace webcrypto {
-
-AesAlgorithm::AesAlgorithm(CK_MECHANISM_TYPE import_mechanism,
- blink::WebCryptoKeyUsageMask all_key_usages,
- const std::string& jwk_suffix)
- : import_mechanism_(import_mechanism),
- all_key_usages_(all_key_usages),
- jwk_suffix_(jwk_suffix) {
-}
-
-AesAlgorithm::AesAlgorithm(CK_MECHANISM_TYPE import_mechanism,
- const std::string& jwk_suffix)
- : import_mechanism_(import_mechanism),
- all_key_usages_(blink::WebCryptoKeyUsageEncrypt |
- blink::WebCryptoKeyUsageDecrypt |
- blink::WebCryptoKeyUsageWrapKey |
- blink::WebCryptoKeyUsageUnwrapKey),
- jwk_suffix_(jwk_suffix) {
-}
-
-Status AesAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- GenerateKeyResult* result) const {
- Status status = CheckKeyCreationUsages(all_key_usages_, usages, false);
- if (status.IsError())
- return status;
-
- unsigned int keylen_bits;
- status = GetAesKeyGenLengthInBits(algorithm.aesKeyGenParams(), &keylen_bits);
- if (status.IsError())
- return status;
-
- return GenerateSecretKeyNss(
- blink::WebCryptoKeyAlgorithm::createAes(algorithm.id(), keylen_bits),
- extractable, usages, keylen_bits, CKM_AES_KEY_GEN, result);
-}
-
-Status AesAlgorithm::VerifyKeyUsagesBeforeImportKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask usages) const {
- switch (format) {
- case blink::WebCryptoKeyFormatRaw:
- case blink::WebCryptoKeyFormatJwk:
- return CheckKeyCreationUsages(all_key_usages_, usages, false);
- default:
- return Status::ErrorUnsupportedImportKeyFormat();
- }
-}
-Status AesAlgorithm::ImportKeyRaw(const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const {
- const unsigned int keylen_bytes = key_data.byte_length();
- Status status = VerifyAesKeyLengthForImport(keylen_bytes);
- if (status.IsError())
- return status;
-
- // No possibility of overflow.
- unsigned int keylen_bits = keylen_bytes * 8;
-
- return ImportKeyRawNss(key_data, blink::WebCryptoKeyAlgorithm::createAes(
- algorithm.id(), keylen_bits),
- extractable, usages, import_mechanism_, key);
-}
-
-Status AesAlgorithm::ImportKeyJwk(const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const {
- std::vector<uint8_t> raw_data;
- Status status = ReadAesSecretKeyJwk(key_data, jwk_suffix_, extractable,
- usages, &raw_data);
- if (status.IsError())
- return status;
-
- return ImportKeyRaw(CryptoData(raw_data), algorithm, extractable, usages,
- key);
-}
-
-Status AesAlgorithm::ExportKeyRaw(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const {
- *buffer = SymKeyNss::Cast(key)->raw_key_data();
- return Status::Success();
-}
-
-Status AesAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const {
- SymKeyNss* sym_key = SymKeyNss::Cast(key);
- const std::vector<uint8_t>& raw_data = sym_key->raw_key_data();
-
- WriteSecretKeyJwk(CryptoData(raw_data),
- MakeJwkAesAlgorithmName(jwk_suffix_, raw_data.size()),
- key.extractable(), key.usages(), buffer);
-
- return Status::Success();
-}
-
-Status AesAlgorithm::SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const {
- key_data->assign(SymKeyNss::Cast(key)->serialized_key_data());
- return Status::Success();
-}
-
-Status AesAlgorithm::DeserializeKeyForClone(
- const blink::WebCryptoKeyAlgorithm& algorithm,
- blink::WebCryptoKeyType type,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- const CryptoData& key_data,
- blink::WebCryptoKey* key) const {
- return ImportKeyRaw(key_data, CreateAlgorithm(algorithm.id()), extractable,
- usages, key);
-}
-
-Status AesAlgorithm::GetKeyLength(
- const blink::WebCryptoAlgorithm& key_length_algorithm,
- bool* has_length_bits,
- unsigned int* length_bits) const {
- return GetAesKeyLength(key_length_algorithm, has_length_bits, length_bits);
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/aes_algorithm_nss.h b/chromium/components/webcrypto/nss/aes_algorithm_nss.h
deleted file mode 100644
index 1d1df1a3a84..00000000000
--- a/chromium/components/webcrypto/nss/aes_algorithm_nss.h
+++ /dev/null
@@ -1,85 +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_WEBCRYPTO_NSS_AES_ALGORITHM_NSS_H_
-#define COMPONENTS_WEBCRYPTO_NSS_AES_ALGORITHM_NSS_H_
-
-#include <pkcs11t.h>
-
-#include "components/webcrypto/algorithm_implementation.h"
-
-namespace webcrypto {
-
-// Base class for AES algorithms that provides the implementation for key
-// creation and export.
-class AesAlgorithm : public AlgorithmImplementation {
- public:
- // Constructs an AES algorithm whose keys will be imported using the NSS
- // mechanism |import_mechanism|.
- // |all_key_usages| is the set of all WebCrypto key usages that are
- // allowed for imported or generated keys. |jwk_suffix| is the suffix
- // used when constructing JWK names for the algorithm. For instance A128CBC
- // is the JWK name for 128-bit AES-CBC. The |jwk_suffix| in this case would
- // be "CBC".
- AesAlgorithm(CK_MECHANISM_TYPE import_mechanism,
- blink::WebCryptoKeyUsageMask all_key_usages,
- const std::string& jwk_suffix);
-
- // This is the same as the other AesAlgorithm constructor, however
- // |all_key_usages| is pre-filled with values for encryption/decryption
- // algorithms (supports usages for: encrypt, decrypt, wrap, unwrap).
- AesAlgorithm(CK_MECHANISM_TYPE import_mechanism,
- const std::string& jwk_suffix);
-
- Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- GenerateKeyResult* result) const override;
-
- Status VerifyKeyUsagesBeforeImportKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask usages) const override;
-
- Status ImportKeyRaw(const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const override;
-
- Status ImportKeyJwk(const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const override;
-
- Status ExportKeyRaw(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const override;
-
- Status ExportKeyJwk(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const override;
-
- Status SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const override;
-
- Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
- blink::WebCryptoKeyType type,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- const CryptoData& key_data,
- blink::WebCryptoKey* key) const override;
-
- Status GetKeyLength(const blink::WebCryptoAlgorithm& key_length_algorithm,
- bool* has_length_bits,
- unsigned int* length_bits) const override;
-
- private:
- const CK_MECHANISM_TYPE import_mechanism_;
- const blink::WebCryptoKeyUsageMask all_key_usages_;
- const std::string jwk_suffix_;
-};
-
-} // namespace webcrypto
-
-#endif // COMPONENTS_WEBCRYPTO_NSS_AES_ALGORITHM_NSS_H_
diff --git a/chromium/components/webcrypto/nss/aes_cbc_nss.cc b/chromium/components/webcrypto/nss/aes_cbc_nss.cc
deleted file mode 100644
index 16748469f1e..00000000000
--- a/chromium/components/webcrypto/nss/aes_cbc_nss.cc
+++ /dev/null
@@ -1,120 +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 <cryptohi.h>
-
-#include "base/numerics/safe_math.h"
-#include "base/stl_util.h"
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/nss/aes_algorithm_nss.h"
-#include "components/webcrypto/nss/key_nss.h"
-#include "components/webcrypto/nss/util_nss.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-#include "crypto/scoped_nss_types.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
-
-namespace webcrypto {
-
-namespace {
-
-Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode,
- const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) {
- const blink::WebCryptoAesCbcParams* params = algorithm.aesCbcParams();
- if (!params)
- return Status::ErrorUnexpected();
-
- CryptoData iv(params->iv().data(), params->iv().size());
- if (iv.byte_length() != 16)
- return Status::ErrorIncorrectSizeAesCbcIv();
-
- PK11SymKey* sym_key = SymKeyNss::Cast(key)->key();
-
- CK_ATTRIBUTE_TYPE operation = (mode == ENCRYPT) ? CKA_ENCRYPT : CKA_DECRYPT;
-
- SECItem iv_item = MakeSECItemForBuffer(iv);
-
- crypto::ScopedSECItem param(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item));
- if (!param)
- return Status::OperationError();
-
- crypto::ScopedPK11Context context(PK11_CreateContextBySymKey(
- CKM_AES_CBC_PAD, operation, sym_key, param.get()));
-
- if (!context.get())
- return Status::OperationError();
-
- // Oddly PK11_CipherOp takes input and output lengths as "int" rather than
- // "unsigned int". Do some checks now to avoid integer overflowing.
- base::CheckedNumeric<int> output_max_len = data.byte_length();
- output_max_len += AES_BLOCK_SIZE;
- if (!output_max_len.IsValid()) {
- // TODO(eroman): Handle this by chunking the input fed into NSS. Right now
- // it doesn't make much difference since the one-shot API would end up
- // blowing out the memory and crashing anyway.
- return Status::ErrorDataTooLarge();
- }
-
- // PK11_CipherOp does an invalid memory access when given empty decryption
- // input, or input which is not a multiple of the block size. See also
- // https://bugzilla.mozilla.com/show_bug.cgi?id=921687.
- if (operation == CKA_DECRYPT &&
- (data.byte_length() == 0 || (data.byte_length() % AES_BLOCK_SIZE != 0))) {
- return Status::OperationError();
- }
-
- // TODO(eroman): Refine the output buffer size. It can be computed exactly for
- // encryption, and can be smaller for decryption.
- buffer->resize(output_max_len.ValueOrDie());
-
- unsigned char* buffer_data = vector_as_array(buffer);
-
- int output_len;
- if (SECSuccess != PK11_CipherOp(context.get(), buffer_data, &output_len,
- buffer->size(), data.bytes(),
- data.byte_length())) {
- return Status::OperationError();
- }
-
- unsigned int final_output_chunk_len;
- if (SECSuccess !=
- PK11_DigestFinal(context.get(), buffer_data + output_len,
- &final_output_chunk_len,
- (output_max_len - output_len).ValueOrDie())) {
- return Status::OperationError();
- }
-
- buffer->resize(final_output_chunk_len + output_len);
- return Status::Success();
-}
-
-class AesCbcImplementation : public AesAlgorithm {
- public:
- AesCbcImplementation() : AesAlgorithm(CKM_AES_CBC, "CBC") {}
-
- Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- return AesCbcEncryptDecrypt(ENCRYPT, algorithm, key, data, buffer);
- }
-
- Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- return AesCbcEncryptDecrypt(DECRYPT, algorithm, key, data, buffer);
- }
-};
-
-} // namespace
-
-AlgorithmImplementation* CreatePlatformAesCbcImplementation() {
- return new AesCbcImplementation;
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/aes_gcm_nss.cc b/chromium/components/webcrypto/nss/aes_gcm_nss.cc
deleted file mode 100644
index e4b8f752e1d..00000000000
--- a/chromium/components/webcrypto/nss/aes_gcm_nss.cc
+++ /dev/null
@@ -1,182 +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 "base/numerics/safe_math.h"
-#include "base/stl_util.h"
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/nss/aes_algorithm_nss.h"
-#include "components/webcrypto/nss/key_nss.h"
-#include "components/webcrypto/nss/util_nss.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
-
-// At the time of this writing:
-// * Windows and Mac builds ship with their own copy of NSS (3.15+)
-// * Linux builds use the system's libnss, which is 3.14 on Debian (but 3.15+
-// on other distros).
-//
-// Since NSS provides AES-GCM support starting in version 3.15, it may be
-// unavailable for Linux Chrome users.
-//
-// * !defined(CKM_AES_GCM)
-//
-// This means that at build time, the NSS header pkcs11t.h is older than
-// 3.15. However at runtime support may be present.
-//
-// TODO(eroman): Simplify this once 3.15+ is required by Linux builds.
-#if !defined(CKM_AES_GCM)
-#define CKM_AES_GCM 0x00001087
-
-struct CK_GCM_PARAMS {
- CK_BYTE_PTR pIv;
- CK_ULONG ulIvLen;
- CK_BYTE_PTR pAAD;
- CK_ULONG ulAADLen;
- CK_ULONG ulTagBits;
-};
-#endif // !defined(CKM_AES_GCM)
-
-namespace webcrypto {
-
-namespace {
-
-Status NssSupportsAesGcm() {
- if (NssRuntimeSupport::Get()->IsAesGcmSupported())
- return Status::Success();
- return Status::ErrorUnsupported(
- "NSS version doesn't support AES-GCM. Try using version 3.15 or later");
-}
-
-// Helper to either encrypt or decrypt for AES-GCM. The result of encryption is
-// the concatenation of the ciphertext and the authentication tag. Similarly,
-// this is the expectation for the input to decryption.
-Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
- const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) {
- Status status = NssSupportsAesGcm();
- if (status.IsError())
- return status;
-
- PK11SymKey* sym_key = SymKeyNss::Cast(key)->key();
- const blink::WebCryptoAesGcmParams* params = algorithm.aesGcmParams();
- if (!params)
- return Status::ErrorUnexpected();
-
- unsigned int tag_length_bits;
- status = GetAesGcmTagLengthInBits(params, &tag_length_bits);
- if (status.IsError())
- return status;
- unsigned int tag_length_bytes = tag_length_bits / 8;
-
- CryptoData iv(params->iv());
- CryptoData additional_data(params->optionalAdditionalData());
-
- CK_GCM_PARAMS gcm_params = {0};
- gcm_params.pIv = const_cast<unsigned char*>(iv.bytes());
- gcm_params.ulIvLen = iv.byte_length();
-
- gcm_params.pAAD = const_cast<unsigned char*>(additional_data.bytes());
- gcm_params.ulAADLen = additional_data.byte_length();
-
- gcm_params.ulTagBits = tag_length_bits;
-
- SECItem param;
- param.type = siBuffer;
- param.data = reinterpret_cast<unsigned char*>(&gcm_params);
- param.len = sizeof(gcm_params);
-
- base::CheckedNumeric<unsigned int> buffer_size(data.byte_length());
-
- // Calculate the output buffer size.
- if (mode == ENCRYPT) {
- buffer_size += tag_length_bytes;
- if (!buffer_size.IsValid())
- return Status::ErrorDataTooLarge();
- }
-
- // TODO(eroman): In theory the buffer allocated for the plain text should be
- // sized as |data.byte_length() - tag_length_bytes|.
- //
- // However NSS has a bug whereby it will fail if the output buffer size is
- // not at least as large as the ciphertext:
- //
- // https://bugzilla.mozilla.org/show_bug.cgi?id=%20853674
- //
- // From the analysis of that bug it looks like it might be safe to pass a
- // correctly sized buffer but lie about its size. Since resizing the
- // WebCryptoArrayBuffer is expensive that hack may be worth looking into.
-
- buffer->resize(buffer_size.ValueOrDie());
- unsigned char* buffer_data = vector_as_array(buffer);
-
- PK11_EncryptDecryptFunction encrypt_or_decrypt_func =
- (mode == ENCRYPT) ? NssRuntimeSupport::Get()->pk11_encrypt_func()
- : NssRuntimeSupport::Get()->pk11_decrypt_func();
-
- unsigned int output_len = 0;
- SECStatus result = encrypt_or_decrypt_func(
- sym_key, CKM_AES_GCM, &param, buffer_data, &output_len, buffer->size(),
- data.bytes(), data.byte_length());
-
- if (result != SECSuccess)
- return Status::OperationError();
-
- // Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug
- // above).
- buffer->resize(output_len);
-
- return Status::Success();
-}
-
-class AesGcmImplementation : public AesAlgorithm {
- public:
- AesGcmImplementation() : AesAlgorithm(CKM_AES_GCM, "GCM") {}
-
- Status VerifyKeyUsagesBeforeImportKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask usages) const override {
- // Prevent importing AES-GCM keys if it is unavailable.
- Status status = NssSupportsAesGcm();
- if (status.IsError())
- return status;
- return AesAlgorithm::VerifyKeyUsagesBeforeImportKey(format, usages);
- }
-
- Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- GenerateKeyResult* result) const override {
- // Prevent generating AES-GCM keys if it is unavailable.
- Status status = NssSupportsAesGcm();
- if (status.IsError())
- return status;
-
- return AesAlgorithm::GenerateKey(algorithm, extractable, usages, result);
- }
-
- Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- return AesGcmEncryptDecrypt(ENCRYPT, algorithm, key, data, buffer);
- }
-
- Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- return AesGcmEncryptDecrypt(DECRYPT, algorithm, key, data, buffer);
- }
-};
-
-} // namespace
-
-AlgorithmImplementation* CreatePlatformAesGcmImplementation() {
- return new AesGcmImplementation;
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/aes_kw_nss.cc b/chromium/components/webcrypto/nss/aes_kw_nss.cc
deleted file mode 100644
index 77afb1fc53b..00000000000
--- a/chromium/components/webcrypto/nss/aes_kw_nss.cc
+++ /dev/null
@@ -1,186 +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 <secerr.h>
-
-#include "base/numerics/safe_math.h"
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/nss/aes_algorithm_nss.h"
-#include "components/webcrypto/nss/key_nss.h"
-#include "components/webcrypto/nss/sym_key_nss.h"
-#include "components/webcrypto/nss/util_nss.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-#include "crypto/scoped_nss_types.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
-#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
-
-namespace webcrypto {
-
-namespace {
-
-// The Default IV for AES-KW. See http://www.ietf.org/rfc/rfc3394.txt
-// Section 2.2.3.1.
-const unsigned char kAesIv[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6};
-
-// The result of unwrapping is a SymKey rather than a buffer. This is a
-// consequence of how NSS exposes AES-KW. Subsequent code can extract the value
-// of the sym key to interpret it as key bytes in another format.
-Status DoUnwrapSymKeyAesKw(const CryptoData& wrapped_key_data,
- PK11SymKey* wrapping_key,
- CK_MECHANISM_TYPE mechanism,
- CK_FLAGS flags,
- crypto::ScopedPK11SymKey* unwrapped_key) {
- DCHECK_GE(wrapped_key_data.byte_length(), 24u);
- DCHECK_EQ(wrapped_key_data.byte_length() % 8, 0u);
-
- SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv)));
- crypto::ScopedSECItem param_item(
- PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item));
- if (!param_item)
- return Status::ErrorUnexpected();
-
- SECItem cipher_text = MakeSECItemForBuffer(wrapped_key_data);
-
- // The plaintext length is always 64 bits less than the data size.
- const unsigned int plaintext_length = wrapped_key_data.byte_length() - 8;
-
-#if defined(USE_NSS_CERTS)
- // Part of workaround for
- // https://bugzilla.mozilla.org/show_bug.cgi?id=981170. See the explanation
- // later in this function.
- PORT_SetError(0);
-#endif
-
- crypto::ScopedPK11SymKey new_key(PK11_UnwrapSymKeyWithFlags(
- wrapping_key, CKM_NSS_AES_KEY_WRAP, param_item.get(), &cipher_text,
- mechanism, CKA_FLAGS_ONLY, plaintext_length, flags));
-
- // TODO(padolph): Use NSS PORT_GetError() and friends to report a more
- // accurate error, providing if doesn't leak any information to web pages
- // about other web crypto users, key details, etc.
- if (!new_key)
- return Status::OperationError();
-
-#if defined(USE_NSS_CERTS)
- // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=981170
- // which was fixed in NSS 3.16.0.
- // If unwrap fails, NSS nevertheless returns a valid-looking PK11SymKey,
- // with a reasonable length but with key data pointing to uninitialized
- // memory.
- // To understand this workaround see the fix for 981170:
- // https://hg.mozilla.org/projects/nss/rev/753bb69e543c
- if (!NSS_VersionCheck("3.16") && PORT_GetError() == SEC_ERROR_BAD_DATA)
- return Status::OperationError();
-#endif
-
- *unwrapped_key = new_key.Pass();
- return Status::Success();
-}
-
-Status WrapSymKeyAesKw(PK11SymKey* key,
- PK11SymKey* wrapping_key,
- std::vector<uint8_t>* buffer) {
- // The data size must be at least 16 bytes and a multiple of 8 bytes.
- // RFC 3394 does not specify a maximum allowed data length, but since only
- // keys are being wrapped in this application (which are small), a reasonable
- // max limit is whatever will fit into an unsigned. For the max size test,
- // note that AES Key Wrap always adds 8 bytes to the input data size.
- const unsigned int input_length = PK11_GetKeyLength(key);
- DCHECK_GE(input_length, 16u);
- DCHECK((input_length % 8) == 0);
-
- SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv)));
- crypto::ScopedSECItem param_item(
- PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item));
- if (!param_item)
- return Status::ErrorUnexpected();
-
- base::CheckedNumeric<unsigned int> output_length = input_length;
- output_length += 8;
- if (!output_length.IsValid())
- return Status::ErrorDataTooLarge();
-
- buffer->resize(output_length.ValueOrDie());
- SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
-
- if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, param_item.get(),
- wrapping_key, key, &wrapped_key_item)) {
- return Status::OperationError();
- }
- if (output_length.ValueOrDie() != wrapped_key_item.len)
- return Status::ErrorUnexpected();
-
- return Status::Success();
-}
-
-class AesKwCryptoAlgorithmNss : public AesAlgorithm {
- public:
- AesKwCryptoAlgorithmNss()
- : AesAlgorithm(
- CKM_NSS_AES_KEY_WRAP,
- blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey,
- "KW") {}
-
- Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& wrapping_key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- if (data.byte_length() < 16)
- return Status::ErrorDataTooSmall();
- if (data.byte_length() % 8)
- return Status::ErrorInvalidAesKwDataLength();
-
- // Due to limitations in the NSS API for the AES-KW algorithm, |data| must
- // be temporarily viewed as a symmetric key to be wrapped (encrypted).
- SECItem data_item = MakeSECItemForBuffer(data);
- crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
- crypto::ScopedPK11SymKey data_as_sym_key(
- PK11_ImportSymKey(slot.get(), CKK_GENERIC_SECRET, PK11_OriginUnwrap,
- CKA_SIGN, &data_item, NULL));
- if (!data_as_sym_key)
- return Status::OperationError();
-
- return WrapSymKeyAesKw(data_as_sym_key.get(),
- SymKeyNss::Cast(wrapping_key)->key(), buffer);
- }
-
- Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& wrapping_key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- if (data.byte_length() < 24)
- return Status::ErrorDataTooSmall();
- if (data.byte_length() % 8)
- return Status::ErrorInvalidAesKwDataLength();
-
- // Due to limitations in the NSS API for the AES-KW algorithm, |data| must
- // be temporarily viewed as a symmetric key to be unwrapped (decrypted).
- crypto::ScopedPK11SymKey decrypted;
- Status status =
- DoUnwrapSymKeyAesKw(data, SymKeyNss::Cast(wrapping_key)->key(),
- CKK_GENERIC_SECRET, 0, &decrypted);
- if (status.IsError())
- return status;
-
- // Once the decrypt is complete, extract the resultant raw bytes from NSS
- // and return them to the caller.
- if (PK11_ExtractKeyValue(decrypted.get()) != SECSuccess)
- return Status::OperationError();
- const SECItem* const key_data = PK11_GetKeyData(decrypted.get());
- if (!key_data)
- return Status::OperationError();
- buffer->assign(key_data->data, key_data->data + key_data->len);
-
- return Status::Success();
- }
-};
-
-} // namespace
-
-AlgorithmImplementation* CreatePlatformAesKwImplementation() {
- return new AesKwCryptoAlgorithmNss;
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/hmac_nss.cc b/chromium/components/webcrypto/nss/hmac_nss.cc
deleted file mode 100644
index f19648d7707..00000000000
--- a/chromium/components/webcrypto/nss/hmac_nss.cc
+++ /dev/null
@@ -1,261 +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 <cryptohi.h>
-#include <pk11pub.h>
-#include <secerr.h>
-#include <sechash.h>
-
-#include "base/logging.h"
-#include "base/stl_util.h"
-#include "components/webcrypto/algorithm_implementation.h"
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/nss/key_nss.h"
-#include "components/webcrypto/nss/sym_key_nss.h"
-#include "components/webcrypto/nss/util_nss.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-#include "crypto/secure_util.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
-#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
-
-namespace webcrypto {
-
-namespace {
-
-const blink::WebCryptoKeyUsageMask kAllKeyUsages =
- blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify;
-
-bool WebCryptoHashToHMACMechanism(const blink::WebCryptoAlgorithm& algorithm,
- CK_MECHANISM_TYPE* mechanism) {
- switch (algorithm.id()) {
- case blink::WebCryptoAlgorithmIdSha1:
- *mechanism = CKM_SHA_1_HMAC;
- return true;
- case blink::WebCryptoAlgorithmIdSha256:
- *mechanism = CKM_SHA256_HMAC;
- return true;
- case blink::WebCryptoAlgorithmIdSha384:
- *mechanism = CKM_SHA384_HMAC;
- return true;
- case blink::WebCryptoAlgorithmIdSha512:
- *mechanism = CKM_SHA512_HMAC;
- return true;
- default:
- return false;
- }
-}
-
-class HmacImplementation : public AlgorithmImplementation {
- public:
- HmacImplementation() {}
-
- Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- GenerateKeyResult* result) const override {
- Status status = CheckKeyCreationUsages(kAllKeyUsages, usages, false);
- if (status.IsError())
- return status;
-
- const blink::WebCryptoHmacKeyGenParams* params =
- algorithm.hmacKeyGenParams();
-
- const blink::WebCryptoAlgorithm& hash = params->hash();
- CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
- if (!WebCryptoHashToHMACMechanism(hash, &mechanism))
- return Status::ErrorUnsupported();
-
- unsigned int keylen_bits = 0;
- status = GetHmacKeyGenLengthInBits(params, &keylen_bits);
- if (status.IsError())
- return status;
-
- return GenerateSecretKeyNss(
- blink::WebCryptoKeyAlgorithm::createHmac(hash.id(), keylen_bits),
- extractable, usages, keylen_bits, mechanism, result);
- }
-
- Status VerifyKeyUsagesBeforeImportKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask usages) const override {
- switch (format) {
- case blink::WebCryptoKeyFormatRaw:
- case blink::WebCryptoKeyFormatJwk:
- return CheckKeyCreationUsages(kAllKeyUsages, usages, false);
- default:
- return Status::ErrorUnsupportedImportKeyFormat();
- }
- }
-
- Status ImportKeyRaw(const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const override {
- const blink::WebCryptoHmacImportParams* params =
- algorithm.hmacImportParams();
-
- CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
- if (!WebCryptoHashToHMACMechanism(params->hash(), &mechanism))
- return Status::ErrorUnsupported();
-
- unsigned int keylen_bits = 0;
- Status status = GetHmacImportKeyLengthBits(params, key_data.byte_length(),
- &keylen_bits);
- if (status.IsError())
- return status;
-
- const blink::WebCryptoKeyAlgorithm key_algorithm =
- blink::WebCryptoKeyAlgorithm::createHmac(params->hash().id(),
- keylen_bits);
-
- // If no bit truncation was requested, then done!
- if ((keylen_bits % 8) == 0) {
- return ImportKeyRawNss(key_data, key_algorithm, extractable, usages,
- mechanism, key);
- }
-
- // Otherwise zero out the unused bits in the key data before importing.
- std::vector<uint8_t> modified_key_data(
- key_data.bytes(), key_data.bytes() + key_data.byte_length());
- TruncateToBitLength(keylen_bits, &modified_key_data);
- return ImportKeyRawNss(CryptoData(modified_key_data), key_algorithm,
- extractable, usages, mechanism, key);
- }
-
- Status ImportKeyJwk(const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const override {
- const char* algorithm_name =
- GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id());
- if (!algorithm_name)
- return Status::ErrorUnexpected();
-
- std::vector<uint8_t> raw_data;
- Status status = ReadSecretKeyJwk(key_data, algorithm_name, extractable,
- usages, &raw_data);
- if (status.IsError())
- return status;
-
- return ImportKeyRaw(CryptoData(raw_data), algorithm, extractable, usages,
- key);
- }
-
- Status ExportKeyRaw(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const override {
- *buffer = SymKeyNss::Cast(key)->raw_key_data();
- return Status::Success();
- }
-
- Status ExportKeyJwk(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const override {
- SymKeyNss* sym_key = SymKeyNss::Cast(key);
- const std::vector<uint8_t>& raw_data = sym_key->raw_key_data();
-
- const char* algorithm_name =
- GetJwkHmacAlgorithmName(key.algorithm().hmacParams()->hash().id());
- if (!algorithm_name)
- return Status::ErrorUnexpected();
-
- WriteSecretKeyJwk(CryptoData(raw_data), algorithm_name, key.extractable(),
- key.usages(), buffer);
-
- return Status::Success();
- }
-
- Status Sign(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- const blink::WebCryptoAlgorithm& hash =
- key.algorithm().hmacParams()->hash();
- PK11SymKey* sym_key = SymKeyNss::Cast(key)->key();
-
- CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
- if (!WebCryptoHashToHMACMechanism(hash, &mechanism))
- return Status::ErrorUnexpected();
-
- SECItem param_item = {siBuffer, NULL, 0};
- SECItem data_item = MakeSECItemForBuffer(data);
- // First call is to figure out the length.
- SECItem signature_item = {siBuffer, NULL, 0};
-
- if (PK11_SignWithSymKey(sym_key, mechanism, &param_item, &signature_item,
- &data_item) != SECSuccess) {
- return Status::OperationError();
- }
-
- DCHECK_NE(0u, signature_item.len);
-
- buffer->resize(signature_item.len);
- signature_item.data = vector_as_array(buffer);
-
- if (PK11_SignWithSymKey(sym_key, mechanism, &param_item, &signature_item,
- &data_item) != SECSuccess) {
- return Status::OperationError();
- }
-
- CHECK_EQ(buffer->size(), signature_item.len);
- return Status::Success();
- }
-
- Status Verify(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& signature,
- const CryptoData& data,
- bool* signature_match) const override {
- std::vector<uint8_t> result;
- Status status = Sign(algorithm, key, data, &result);
-
- if (status.IsError())
- return status;
-
- // Do not allow verification of truncated MACs.
- *signature_match =
- result.size() == signature.byte_length() &&
- crypto::SecureMemEqual(vector_as_array(&result), signature.bytes(),
- signature.byte_length());
-
- return Status::Success();
- }
-
- Status SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const override {
- key_data->assign(SymKeyNss::Cast(key)->serialized_key_data());
- return Status::Success();
- }
-
- Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
- blink::WebCryptoKeyType type,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- const CryptoData& key_data,
- blink::WebCryptoKey* key) const override {
- CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
- if (!WebCryptoHashToHMACMechanism(algorithm.hmacParams()->hash(),
- &mechanism))
- return Status::ErrorUnsupported();
- return ImportKeyRawNss(key_data, algorithm, extractable, usages, mechanism,
- key);
- }
-
- Status GetKeyLength(const blink::WebCryptoAlgorithm& key_length_algorithm,
- bool* has_length_bits,
- unsigned int* length_bits) const override {
- return GetHmacKeyLength(key_length_algorithm, has_length_bits, length_bits);
- }
-};
-
-} // namespace
-
-AlgorithmImplementation* CreatePlatformHmacImplementation() {
- return new HmacImplementation;
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/key_nss.cc b/chromium/components/webcrypto/nss/key_nss.cc
deleted file mode 100644
index 92f26c3e1ab..00000000000
--- a/chromium/components/webcrypto/nss/key_nss.cc
+++ /dev/null
@@ -1,85 +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/webcrypto/nss/key_nss.h"
-
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-
-namespace webcrypto {
-
-KeyNss::KeyNss(const CryptoData& serialized_key_data)
- : serialized_key_data_(
- serialized_key_data.bytes(),
- serialized_key_data.bytes() + serialized_key_data.byte_length()) {
-}
-
-KeyNss::~KeyNss() {
-}
-
-SymKeyNss* KeyNss::AsSymKey() {
- return NULL;
-}
-
-PublicKeyNss* KeyNss::AsPublicKey() {
- return NULL;
-}
-
-PrivateKeyNss* KeyNss::AsPrivateKey() {
- return NULL;
-}
-
-SymKeyNss::~SymKeyNss() {
-}
-
-SymKeyNss* SymKeyNss::Cast(const blink::WebCryptoKey& key) {
- KeyNss* platform_key = reinterpret_cast<KeyNss*>(key.handle());
- return platform_key->AsSymKey();
-}
-
-SymKeyNss* SymKeyNss::AsSymKey() {
- return this;
-}
-
-SymKeyNss::SymKeyNss(crypto::ScopedPK11SymKey key,
- const CryptoData& raw_key_data)
- : KeyNss(raw_key_data), key_(key.Pass()) {
-}
-
-PublicKeyNss::~PublicKeyNss() {
-}
-
-PublicKeyNss* PublicKeyNss::Cast(const blink::WebCryptoKey& key) {
- KeyNss* platform_key = reinterpret_cast<KeyNss*>(key.handle());
- return platform_key->AsPublicKey();
-}
-
-PublicKeyNss* PublicKeyNss::AsPublicKey() {
- return this;
-}
-
-PublicKeyNss::PublicKeyNss(crypto::ScopedSECKEYPublicKey key,
- const CryptoData& spki_data)
- : KeyNss(spki_data), key_(key.Pass()) {
-}
-
-PrivateKeyNss::~PrivateKeyNss() {
-}
-
-PrivateKeyNss* PrivateKeyNss::Cast(const blink::WebCryptoKey& key) {
- KeyNss* platform_key = reinterpret_cast<KeyNss*>(key.handle());
- return platform_key->AsPrivateKey();
-}
-
-PrivateKeyNss* PrivateKeyNss::AsPrivateKey() {
- return this;
-}
-
-PrivateKeyNss::PrivateKeyNss(crypto::ScopedSECKEYPrivateKey key,
- const CryptoData& pkcs8_data)
- : KeyNss(pkcs8_data), key_(key.Pass()) {
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/key_nss.h b/chromium/components/webcrypto/nss/key_nss.h
deleted file mode 100644
index e3127d8d58f..00000000000
--- a/chromium/components/webcrypto/nss/key_nss.h
+++ /dev/null
@@ -1,105 +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_WEBCRYPTO_NSS_KEY_NSS_H_
-#define COMPONENTS_WEBCRYPTO_NSS_KEY_NSS_H_
-
-#include <stdint.h>
-#include <vector>
-
-#include "crypto/scoped_nss_types.h"
-#include "third_party/WebKit/public/platform/WebCryptoKey.h"
-
-namespace webcrypto {
-
-class CryptoData;
-class PrivateKeyNss;
-class PublicKeyNss;
-class SymKeyNss;
-
-// Base key class for all NSS keys, used to safely cast between types. Each key
-// maintains a copy of its serialized form in either 'raw', 'pkcs8', or 'spki'
-// format. This is to allow structured cloning of keys synchronously from the
-// target Blink thread without having to lock access to the key.
-class KeyNss : public blink::WebCryptoKeyHandle {
- public:
- explicit KeyNss(const CryptoData& serialized_key_data);
- ~KeyNss() override;
-
- virtual SymKeyNss* AsSymKey();
- virtual PublicKeyNss* AsPublicKey();
- virtual PrivateKeyNss* AsPrivateKey();
-
- const std::vector<uint8_t>& serialized_key_data() const {
- return serialized_key_data_;
- }
-
- private:
- const std::vector<uint8_t> serialized_key_data_;
-};
-
-class SymKeyNss : public KeyNss {
- public:
- ~SymKeyNss() override;
- SymKeyNss(crypto::ScopedPK11SymKey key, const CryptoData& raw_key_data);
-
- static SymKeyNss* Cast(const blink::WebCryptoKey& key);
-
- PK11SymKey* key() { return key_.get(); }
- SymKeyNss* AsSymKey() override;
-
- const std::vector<uint8_t>& raw_key_data() const {
- return serialized_key_data();
- }
-
- private:
- crypto::ScopedPK11SymKey key_;
-
- DISALLOW_COPY_AND_ASSIGN(SymKeyNss);
-};
-
-class PublicKeyNss : public KeyNss {
- public:
- ~PublicKeyNss() override;
- PublicKeyNss(crypto::ScopedSECKEYPublicKey key, const CryptoData& spki_data);
-
- static PublicKeyNss* Cast(const blink::WebCryptoKey& key);
-
- SECKEYPublicKey* key() { return key_.get(); }
- PublicKeyNss* AsPublicKey() override;
-
- const std::vector<uint8_t>& spki_data() const {
- return serialized_key_data();
- }
-
- private:
- crypto::ScopedSECKEYPublicKey key_;
-
- DISALLOW_COPY_AND_ASSIGN(PublicKeyNss);
-};
-
-class PrivateKeyNss : public KeyNss {
- public:
- ~PrivateKeyNss() override;
- PrivateKeyNss(crypto::ScopedSECKEYPrivateKey key,
- const CryptoData& pkcs8_data);
-
- static PrivateKeyNss* Cast(const blink::WebCryptoKey& key);
-
- SECKEYPrivateKey* key() { return key_.get(); }
- PrivateKeyNss* AsPrivateKey() override;
-
- const std::vector<uint8_t>& pkcs8_data() const {
- return serialized_key_data();
- }
-
- private:
- crypto::ScopedSECKEYPrivateKey key_;
-
- DISALLOW_COPY_AND_ASSIGN(PrivateKeyNss);
-};
-
-} // namespace webcrypto
-
-#endif // COMPONENTS_WEBCRYPTO_NSS_KEY_NSS_H_
diff --git a/chromium/components/webcrypto/nss/rsa_hashed_algorithm_nss.cc b/chromium/components/webcrypto/nss/rsa_hashed_algorithm_nss.cc
deleted file mode 100644
index 1b7e4a2df4e..00000000000
--- a/chromium/components/webcrypto/nss/rsa_hashed_algorithm_nss.cc
+++ /dev/null
@@ -1,858 +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/webcrypto/nss/rsa_hashed_algorithm_nss.h"
-
-#include <secasn1.h>
-
-#include "base/logging.h"
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/generate_key_result.h"
-#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/nss/key_nss.h"
-#include "components/webcrypto/nss/util_nss.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-#include "crypto/scoped_nss_types.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
-#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
-
-namespace webcrypto {
-
-namespace {
-
-#if defined(USE_NSS_CERTS) && !defined(OS_CHROMEOS)
-Status ErrorRsaPrivateKeyImportNotSupported() {
- return Status::ErrorUnsupported(
- "NSS version must be at least 3.16.2 for RSA private key import. See "
- "http://crbug.com/380424");
-}
-
-// Prior to NSS 3.16.2 RSA key parameters were not validated. This is
-// a security problem for RSA private key import from JWK which uses a
-// CKA_ID based on the public modulus to retrieve the private key.
-Status NssSupportsRsaPrivateKeyImport() {
- if (!NSS_VersionCheck("3.16.2"))
- return ErrorRsaPrivateKeyImportNotSupported();
-
- // Also ensure that the version of Softoken is 3.16.2 or later.
- crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
- CK_SLOT_INFO info = {};
- if (PK11_GetSlotInfo(slot.get(), &info) != SECSuccess)
- return ErrorRsaPrivateKeyImportNotSupported();
-
- // CK_SLOT_INFO.hardwareVersion contains the major.minor
- // version info for Softoken in the corresponding .major/.minor
- // fields, and .firmwareVersion contains the patch.build
- // version info (in the .major/.minor fields)
- if ((info.hardwareVersion.major > 3) ||
- (info.hardwareVersion.major == 3 &&
- (info.hardwareVersion.minor > 16 ||
- (info.hardwareVersion.minor == 16 &&
- info.firmwareVersion.major >= 2)))) {
- return Status::Success();
- }
-
- return ErrorRsaPrivateKeyImportNotSupported();
-}
-#else
-Status NssSupportsRsaPrivateKeyImport() {
- return Status::Success();
-}
-#endif
-
-bool CreateRsaHashedPublicKeyAlgorithm(
- blink::WebCryptoAlgorithmId rsa_algorithm,
- blink::WebCryptoAlgorithmId hash_algorithm,
- SECKEYPublicKey* key,
- blink::WebCryptoKeyAlgorithm* key_algorithm) {
- // TODO(eroman): What about other key types rsaPss, rsaOaep.
- if (!key || key->keyType != rsaKey)
- return false;
-
- unsigned int modulus_length_bits = SECKEY_PublicKeyStrength(key) * 8;
- CryptoData public_exponent(key->u.rsa.publicExponent.data,
- key->u.rsa.publicExponent.len);
-
- *key_algorithm = blink::WebCryptoKeyAlgorithm::createRsaHashed(
- rsa_algorithm, modulus_length_bits, public_exponent.bytes(),
- public_exponent.byte_length(), hash_algorithm);
- return true;
-}
-
-bool CreateRsaHashedPrivateKeyAlgorithm(
- blink::WebCryptoAlgorithmId rsa_algorithm,
- blink::WebCryptoAlgorithmId hash_algorithm,
- SECKEYPrivateKey* key,
- blink::WebCryptoKeyAlgorithm* key_algorithm) {
- crypto::ScopedSECKEYPublicKey public_key(SECKEY_ConvertToPublicKey(key));
- if (!public_key)
- return false;
- return CreateRsaHashedPublicKeyAlgorithm(rsa_algorithm, hash_algorithm,
- public_key.get(), key_algorithm);
-}
-
-// From PKCS#1 [http://tools.ietf.org/html/rfc3447]:
-//
-// RSAPrivateKey ::= SEQUENCE {
-// version Version,
-// modulus INTEGER, -- n
-// publicExponent INTEGER, -- e
-// privateExponent INTEGER, -- d
-// prime1 INTEGER, -- p
-// prime2 INTEGER, -- q
-// exponent1 INTEGER, -- d mod (p-1)
-// exponent2 INTEGER, -- d mod (q-1)
-// coefficient INTEGER, -- (inverse of q) mod p
-// otherPrimeInfos OtherPrimeInfos OPTIONAL
-// }
-//
-// Note that otherPrimeInfos is only applicable for version=1. Since NSS
-// doesn't use multi-prime can safely use version=0.
-struct RSAPrivateKey {
- SECItem version;
- SECItem modulus;
- SECItem public_exponent;
- SECItem private_exponent;
- SECItem prime1;
- SECItem prime2;
- SECItem exponent1;
- SECItem exponent2;
- SECItem coefficient;
-};
-
-// The system NSS library doesn't have the new PK11_ExportDERPrivateKeyInfo
-// function yet (https://bugzilla.mozilla.org/show_bug.cgi?id=519255). So we
-// provide a fallback implementation.
-#if defined(USE_NSS_CERTS)
-const SEC_ASN1Template RSAPrivateKeyTemplate[] = {
- {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(RSAPrivateKey)},
- {SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, version)},
- {SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, modulus)},
- {SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, public_exponent)},
- {SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, private_exponent)},
- {SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, prime1)},
- {SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, prime2)},
- {SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, exponent1)},
- {SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, exponent2)},
- {SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, coefficient)},
- {0}};
-#endif // defined(USE_NSS_CERTS)
-
-// On success |value| will be filled with data which must be freed by
-// SECITEM_FreeItem(value, PR_FALSE);
-bool ReadUint(SECKEYPrivateKey* key,
- CK_ATTRIBUTE_TYPE attribute,
- SECItem* value) {
- SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, key, attribute, value);
-
- // PK11_ReadRawAttribute() returns items of type siBuffer. However in order
- // for the ASN.1 encoding to be correct, the items must be of type
- // siUnsignedInteger.
- value->type = siUnsignedInteger;
-
- return rv == SECSuccess;
-}
-
-// Fills |out| with the RSA private key properties. Returns true on success.
-// Regardless of the return value, the caller must invoke FreeRSAPrivateKey()
-// to free up any allocated memory.
-//
-// The passed in RSAPrivateKey must be zero-initialized.
-bool InitRSAPrivateKey(SECKEYPrivateKey* key, RSAPrivateKey* out) {
- if (key->keyType != rsaKey)
- return false;
-
- // Everything should be zero-ed out. These are just some spot checks.
- DCHECK(!out->version.data);
- DCHECK(!out->version.len);
- DCHECK(!out->modulus.data);
- DCHECK(!out->modulus.len);
-
- // Always use version=0 since not using multi-prime.
- if (!SEC_ASN1EncodeInteger(NULL, &out->version, 0))
- return false;
-
- if (!ReadUint(key, CKA_MODULUS, &out->modulus))
- return false;
- if (!ReadUint(key, CKA_PUBLIC_EXPONENT, &out->public_exponent))
- return false;
- if (!ReadUint(key, CKA_PRIVATE_EXPONENT, &out->private_exponent))
- return false;
- if (!ReadUint(key, CKA_PRIME_1, &out->prime1))
- return false;
- if (!ReadUint(key, CKA_PRIME_2, &out->prime2))
- return false;
- if (!ReadUint(key, CKA_EXPONENT_1, &out->exponent1))
- return false;
- if (!ReadUint(key, CKA_EXPONENT_2, &out->exponent2))
- return false;
- if (!ReadUint(key, CKA_COEFFICIENT, &out->coefficient))
- return false;
-
- return true;
-}
-
-struct FreeRsaPrivateKey {
- void operator()(RSAPrivateKey* out) {
- SECITEM_FreeItem(&out->version, PR_FALSE);
- SECITEM_FreeItem(&out->modulus, PR_FALSE);
- SECITEM_FreeItem(&out->public_exponent, PR_FALSE);
- SECITEM_FreeItem(&out->private_exponent, PR_FALSE);
- SECITEM_FreeItem(&out->prime1, PR_FALSE);
- SECITEM_FreeItem(&out->prime2, PR_FALSE);
- SECITEM_FreeItem(&out->exponent1, PR_FALSE);
- SECITEM_FreeItem(&out->exponent2, PR_FALSE);
- SECITEM_FreeItem(&out->coefficient, PR_FALSE);
- }
-};
-
-typedef scoped_ptr<CERTSubjectPublicKeyInfo,
- crypto::NSSDestroyer<CERTSubjectPublicKeyInfo,
- SECKEY_DestroySubjectPublicKeyInfo>>
- ScopedCERTSubjectPublicKeyInfo;
-
-struct DestroyGenericObject {
- void operator()(PK11GenericObject* o) const {
- if (o)
- PK11_DestroyGenericObject(o);
- }
-};
-
-typedef scoped_ptr<PK11GenericObject, DestroyGenericObject>
- ScopedPK11GenericObject;
-
-// Helper to add an attribute to a template.
-void AddAttribute(CK_ATTRIBUTE_TYPE type,
- void* value,
- unsigned long length,
- std::vector<CK_ATTRIBUTE>* templ) {
- CK_ATTRIBUTE attribute = {type, value, length};
- templ->push_back(attribute);
-}
-
-void AddAttribute(CK_ATTRIBUTE_TYPE type,
- const CryptoData& data,
- std::vector<CK_ATTRIBUTE>* templ) {
- CK_ATTRIBUTE attribute = {
- type, const_cast<unsigned char*>(data.bytes()), data.byte_length()};
- templ->push_back(attribute);
-}
-
-void AddAttribute(CK_ATTRIBUTE_TYPE type,
- const std::string& data,
- std::vector<CK_ATTRIBUTE>* templ) {
- AddAttribute(type, CryptoData(data), templ);
-}
-
-Status ExportKeyPkcs8Nss(SECKEYPrivateKey* key, std::vector<uint8_t>* buffer) {
- if (key->keyType != rsaKey)
- return Status::ErrorUnsupported();
-
-// TODO(rsleevi): Implement OAEP support according to the spec.
-
-#if defined(USE_NSS_CERTS)
- // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code.
- const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
- const int kPrivateKeyInfoVersion = 0;
-
- SECKEYPrivateKeyInfo private_key_info = {};
- RSAPrivateKey rsa_private_key = {};
- scoped_ptr<RSAPrivateKey, FreeRsaPrivateKey> free_private_key(
- &rsa_private_key);
-
- // http://crbug.com/366427: the spec does not define any other failures for
- // exporting, so none of the subsequent errors are spec compliant.
- if (!InitRSAPrivateKey(key, &rsa_private_key))
- return Status::OperationError();
-
- crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
- if (!arena.get())
- return Status::OperationError();
-
- if (!SEC_ASN1EncodeItem(arena.get(), &private_key_info.privateKey,
- &rsa_private_key, RSAPrivateKeyTemplate)) {
- return Status::OperationError();
- }
-
- if (SECSuccess != SECOID_SetAlgorithmID(arena.get(),
- &private_key_info.algorithm,
- algorithm, NULL)) {
- return Status::OperationError();
- }
-
- if (!SEC_ASN1EncodeInteger(arena.get(), &private_key_info.version,
- kPrivateKeyInfoVersion)) {
- return Status::OperationError();
- }
-
- crypto::ScopedSECItem encoded_key(
- SEC_ASN1EncodeItem(NULL, NULL, &private_key_info,
- SEC_ASN1_GET(SECKEY_PrivateKeyInfoTemplate)));
-#else // defined(USE_NSS_CERTS)
- crypto::ScopedSECItem encoded_key(PK11_ExportDERPrivateKeyInfo(key, NULL));
-#endif // defined(USE_NSS_CERTS)
-
- if (!encoded_key.get())
- return Status::OperationError();
-
- buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len);
- return Status::Success();
-}
-
-Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- const JwkRsaInfo& params,
- blink::WebCryptoKey* key) {
- Status status = NssSupportsRsaPrivateKeyImport();
- if (status.IsError())
- return status;
-
- CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY;
- CK_KEY_TYPE key_type = CKK_RSA;
- CK_BBOOL ck_false = CK_FALSE;
-
- std::vector<CK_ATTRIBUTE> key_template;
-
- AddAttribute(CKA_CLASS, &obj_class, sizeof(obj_class), &key_template);
- AddAttribute(CKA_KEY_TYPE, &key_type, sizeof(key_type), &key_template);
- AddAttribute(CKA_TOKEN, &ck_false, sizeof(ck_false), &key_template);
- AddAttribute(CKA_SENSITIVE, &ck_false, sizeof(ck_false), &key_template);
- AddAttribute(CKA_PRIVATE, &ck_false, sizeof(ck_false), &key_template);
-
- // Required properties by JWA.
- AddAttribute(CKA_MODULUS, params.n, &key_template);
- AddAttribute(CKA_PUBLIC_EXPONENT, params.e, &key_template);
- AddAttribute(CKA_PRIVATE_EXPONENT, params.d, &key_template);
-
- // Manufacture a CKA_ID so the created key can be retrieved later as a
- // SECKEYPrivateKey using FindKeyByKeyID(). Unfortunately there isn't a more
- // direct way to do this in NSS.
- //
- // For consistency with other NSS key creation methods, set the CKA_ID to
- // PK11_MakeIDFromPubKey(). There are some problems with
- // this approach:
- //
- // (1) Prior to NSS 3.16.2, there is no parameter validation when creating
- // private keys. It is therefore possible to construct a key using the
- // known public modulus, and where all the other parameters are bogus.
- // FindKeyByKeyID() returns the first key matching the ID. So this would
- // effectively allow an attacker to retrieve a private key of their
- // choice.
- //
- // (2) The ID space is shared by different key types. So theoretically
- // possible to retrieve a key of the wrong type which has a matching
- // CKA_ID. In practice I am told this is not likely except for small key
- // sizes, since would require constructing keys with the same public
- // data.
- //
- // (3) FindKeyByKeyID() doesn't necessarily return the object that was just
- // created by CreateGenericObject. If the pre-existing key was
- // provisioned with flags incompatible with WebCrypto (for instance
- // marked sensitive) then this will break things.
- SECItem modulus_item = MakeSECItemForBuffer(CryptoData(params.n));
- crypto::ScopedSECItem object_id(PK11_MakeIDFromPubKey(&modulus_item));
- AddAttribute(CKA_ID, CryptoData(object_id->data, object_id->len),
- &key_template);
-
- // Optional properties by JWA, however guaranteed to be present by Chromium's
- // implementation.
- AddAttribute(CKA_PRIME_1, params.p, &key_template);
- AddAttribute(CKA_PRIME_2, params.q, &key_template);
- AddAttribute(CKA_EXPONENT_1, params.dp, &key_template);
- AddAttribute(CKA_EXPONENT_2, params.dq, &key_template);
- AddAttribute(CKA_COEFFICIENT, params.qi, &key_template);
-
- crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
-
- ScopedPK11GenericObject key_object(PK11_CreateGenericObject(
- slot.get(), &key_template[0], key_template.size(), PR_FALSE));
-
- if (!key_object)
- return Status::OperationError();
-
- crypto::ScopedSECKEYPrivateKey private_key_tmp(
- PK11_FindKeyByKeyID(slot.get(), object_id.get(), NULL));
-
- // PK11_FindKeyByKeyID() may return a handle to an existing key, rather than
- // the object created by PK11_CreateGenericObject().
- crypto::ScopedSECKEYPrivateKey private_key(
- SECKEY_CopyPrivateKey(private_key_tmp.get()));
-
- if (!private_key)
- return Status::OperationError();
-
- blink::WebCryptoKeyAlgorithm key_algorithm;
- if (!CreateRsaHashedPrivateKeyAlgorithm(
- algorithm.id(), algorithm.rsaHashedImportParams()->hash().id(),
- private_key.get(), &key_algorithm)) {
- return Status::ErrorUnexpected();
- }
-
- std::vector<uint8_t> pkcs8_data;
- status = ExportKeyPkcs8Nss(private_key.get(), &pkcs8_data);
- if (status.IsError())
- return status;
-
- scoped_ptr<PrivateKeyNss> key_handle(
- new PrivateKeyNss(private_key.Pass(), CryptoData(pkcs8_data)));
-
- *key = blink::WebCryptoKey::create(key_handle.release(),
- blink::WebCryptoKeyTypePrivate,
- extractable, key_algorithm, usages);
- return Status::Success();
-}
-
-Status ExportKeySpkiNss(SECKEYPublicKey* key, std::vector<uint8_t>* buffer) {
- const crypto::ScopedSECItem spki_der(
- SECKEY_EncodeDERSubjectPublicKeyInfo(key));
- if (!spki_der)
- return Status::OperationError();
-
- buffer->assign(spki_der->data, spki_der->data + spki_der->len);
- return Status::Success();
-}
-
-Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- const CryptoData& modulus_data,
- const CryptoData& exponent_data,
- blink::WebCryptoKey* key) {
- if (!modulus_data.byte_length())
- return Status::ErrorImportRsaEmptyModulus();
-
- if (!exponent_data.byte_length())
- return Status::ErrorImportRsaEmptyExponent();
-
- DCHECK(modulus_data.bytes());
- DCHECK(exponent_data.bytes());
-
- // NSS does not provide a way to create an RSA public key directly from the
- // modulus and exponent values, but it can import an DER-encoded ASN.1 blob
- // with these values and create the public key from that. The code below
- // follows the recommendation described in
- // https://developer.mozilla.org/en-US/docs/NSS/NSS_Tech_Notes/nss_tech_note7
-
- // Pack the input values into a struct compatible with NSS ASN.1 encoding, and
- // set up an ASN.1 encoder template for it.
- struct RsaPublicKeyData {
- SECItem modulus;
- SECItem exponent;
- };
- const RsaPublicKeyData pubkey_in = {
- {siUnsignedInteger,
- const_cast<unsigned char*>(modulus_data.bytes()),
- modulus_data.byte_length()},
- {siUnsignedInteger,
- const_cast<unsigned char*>(exponent_data.bytes()),
- exponent_data.byte_length()}};
- const SEC_ASN1Template rsa_public_key_template[] = {
- {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(RsaPublicKeyData)},
- {
- SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, modulus),
- },
- {
- SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, exponent),
- },
- {
- 0, }};
-
- // DER-encode the public key.
- crypto::ScopedSECItem pubkey_der(
- SEC_ASN1EncodeItem(NULL, NULL, &pubkey_in, rsa_public_key_template));
- if (!pubkey_der)
- return Status::OperationError();
-
- // Import the DER-encoded public key to create an RSA SECKEYPublicKey.
- crypto::ScopedSECKEYPublicKey pubkey(
- SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA));
- if (!pubkey)
- return Status::OperationError();
-
- blink::WebCryptoKeyAlgorithm key_algorithm;
- if (!CreateRsaHashedPublicKeyAlgorithm(
- algorithm.id(), algorithm.rsaHashedImportParams()->hash().id(),
- pubkey.get(), &key_algorithm)) {
- return Status::ErrorUnexpected();
- }
-
- std::vector<uint8_t> spki_data;
- Status status = ExportKeySpkiNss(pubkey.get(), &spki_data);
- if (status.IsError())
- return status;
-
- scoped_ptr<PublicKeyNss> key_handle(
- new PublicKeyNss(pubkey.Pass(), CryptoData(spki_data)));
-
- *key = blink::WebCryptoKey::create(key_handle.release(),
- blink::WebCryptoKeyTypePublic, extractable,
- key_algorithm, usages);
- return Status::Success();
-}
-
-} // namespace
-
-Status RsaHashedAlgorithm::GenerateKey(
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask combined_usages,
- GenerateKeyResult* result) const {
- blink::WebCryptoKeyUsageMask public_usages = 0;
- blink::WebCryptoKeyUsageMask private_usages = 0;
-
- Status status = GetUsagesForGenerateAsymmetricKey(
- combined_usages, all_public_key_usages_, all_private_key_usages_,
- &public_usages, &private_usages);
- if (status.IsError())
- return status;
-
- unsigned int public_exponent = 0;
- unsigned int modulus_length_bits = 0;
- status = GetRsaKeyGenParameters(algorithm.rsaHashedKeyGenParams(),
- &public_exponent, &modulus_length_bits);
- if (status.IsError())
- return status;
-
- crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
- if (!slot)
- return Status::OperationError();
-
- PK11RSAGenParams rsa_gen_params;
- rsa_gen_params.keySizeInBits = modulus_length_bits;
- rsa_gen_params.pe = public_exponent;
-
- // The usages are enforced at the WebCrypto layer, so it isn't necessary to
- // create keys with limited usages.
- const CK_FLAGS operation_flags_mask = kAllOperationFlags;
-
- // The private key must be marked as insensitive and extractable, otherwise it
- // cannot later be exported in unencrypted form or structured-cloned.
- const PK11AttrFlags attribute_flags =
- PK11_ATTR_INSENSITIVE | PK11_ATTR_EXTRACTABLE;
-
- // Note: NSS does not generate an sec_public_key if the call below fails,
- // so there is no danger of a leaked sec_public_key.
- SECKEYPublicKey* sec_public_key;
- crypto::ScopedSECKEYPrivateKey scoped_sec_private_key(
- PK11_GenerateKeyPairWithOpFlags(slot.get(), CKM_RSA_PKCS_KEY_PAIR_GEN,
- &rsa_gen_params, &sec_public_key,
- attribute_flags, generate_flags_,
- operation_flags_mask, NULL));
- if (!scoped_sec_private_key)
- return Status::OperationError();
-
- blink::WebCryptoKeyAlgorithm key_algorithm;
- if (!CreateRsaHashedPublicKeyAlgorithm(
- algorithm.id(), algorithm.rsaHashedKeyGenParams()->hash().id(),
- sec_public_key, &key_algorithm)) {
- return Status::ErrorUnexpected();
- }
-
- std::vector<uint8_t> spki_data;
- status = ExportKeySpkiNss(sec_public_key, &spki_data);
- if (status.IsError())
- return status;
-
- scoped_ptr<PublicKeyNss> public_key_handle(new PublicKeyNss(
- crypto::ScopedSECKEYPublicKey(sec_public_key), CryptoData(spki_data)));
-
- std::vector<uint8_t> pkcs8_data;
- status = ExportKeyPkcs8Nss(scoped_sec_private_key.get(), &pkcs8_data);
- if (status.IsError())
- return status;
-
- scoped_ptr<PrivateKeyNss> private_key_handle(
- new PrivateKeyNss(scoped_sec_private_key.Pass(), CryptoData(pkcs8_data)));
-
- blink::WebCryptoKey public_key = blink::WebCryptoKey::create(
- public_key_handle.release(), blink::WebCryptoKeyTypePublic, true,
- key_algorithm, public_usages);
-
- blink::WebCryptoKey private_key = blink::WebCryptoKey::create(
- private_key_handle.release(), blink::WebCryptoKeyTypePrivate, extractable,
- key_algorithm, private_usages);
-
- result->AssignKeyPair(public_key, private_key);
- return Status::Success();
-}
-
-Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask usages) const {
- return VerifyUsagesBeforeImportAsymmetricKey(format, all_public_key_usages_,
- all_private_key_usages_, usages);
-}
-
-Status RsaHashedAlgorithm::ImportKeyPkcs8(
- const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const {
- Status status = NssSupportsRsaPrivateKeyImport();
- if (status.IsError())
- return status;
-
- crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
- if (!arena.get())
- return Status::OperationError();
-
- // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8
- // private key info object. Excess data is illegal, but NSS silently accepts
- // it, so first ensure that 'key_data' consists of a single ASN.1 element.
- SECItem key_item = MakeSECItemForBuffer(key_data);
- SECItem pki_der;
- if (SEC_QuickDERDecodeItem(arena.get(), &pki_der,
- SEC_ASN1_GET(SEC_AnyTemplate),
- &key_item) != SECSuccess) {
- return Status::DataError();
- }
-
- SECKEYPrivateKey* seckey_private_key = NULL;
- crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
- if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot.get(), &pki_der,
- NULL, // nickname
- NULL, // publicValue
- false, // isPerm
- false, // isPrivate
- KU_ALL, // usage
- &seckey_private_key,
- NULL) != SECSuccess) {
- return Status::DataError();
- }
- DCHECK(seckey_private_key);
- crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key);
-
- const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get());
- if (sec_key_type != rsaKey)
- return Status::DataError();
-
- blink::WebCryptoKeyAlgorithm key_algorithm;
- if (!CreateRsaHashedPrivateKeyAlgorithm(
- algorithm.id(), algorithm.rsaHashedImportParams()->hash().id(),
- private_key.get(), &key_algorithm)) {
- return Status::ErrorUnexpected();
- }
-
- // TODO(eroman): This is probably going to be the same as the input.
- std::vector<uint8_t> pkcs8_data;
- status = ExportKeyPkcs8Nss(private_key.get(), &pkcs8_data);
- if (status.IsError())
- return status;
-
- scoped_ptr<PrivateKeyNss> key_handle(
- new PrivateKeyNss(private_key.Pass(), CryptoData(pkcs8_data)));
-
- *key = blink::WebCryptoKey::create(key_handle.release(),
- blink::WebCryptoKeyTypePrivate,
- extractable, key_algorithm, usages);
-
- return Status::Success();
-}
-
-Status RsaHashedAlgorithm::ImportKeySpki(
- const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const {
- // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject
- // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo.
- SECItem spki_item = MakeSECItemForBuffer(key_data);
- const ScopedCERTSubjectPublicKeyInfo spki(
- SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
- if (!spki)
- return Status::DataError();
-
- crypto::ScopedSECKEYPublicKey sec_public_key(
- SECKEY_ExtractPublicKey(spki.get()));
- if (!sec_public_key)
- return Status::DataError();
-
- const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get());
- if (sec_key_type != rsaKey)
- return Status::DataError();
-
- blink::WebCryptoKeyAlgorithm key_algorithm;
- if (!CreateRsaHashedPublicKeyAlgorithm(
- algorithm.id(), algorithm.rsaHashedImportParams()->hash().id(),
- sec_public_key.get(), &key_algorithm)) {
- return Status::ErrorUnexpected();
- }
-
- // TODO(eroman): This is probably going to be the same as the input.
- std::vector<uint8_t> spki_data;
- Status status = ExportKeySpkiNss(sec_public_key.get(), &spki_data);
- if (status.IsError())
- return status;
-
- scoped_ptr<PublicKeyNss> key_handle(
- new PublicKeyNss(sec_public_key.Pass(), CryptoData(spki_data)));
-
- *key = blink::WebCryptoKey::create(key_handle.release(),
- blink::WebCryptoKeyTypePublic, extractable,
- key_algorithm, usages);
-
- return Status::Success();
-}
-
-Status RsaHashedAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const {
- if (key.type() != blink::WebCryptoKeyTypePrivate)
- return Status::ErrorUnexpectedKeyType();
- *buffer = PrivateKeyNss::Cast(key)->pkcs8_data();
- return Status::Success();
-}
-
-Status RsaHashedAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const {
- if (key.type() != blink::WebCryptoKeyTypePublic)
- return Status::ErrorUnexpectedKeyType();
- *buffer = PublicKeyNss::Cast(key)->spki_data();
- return Status::Success();
-}
-
-Status RsaHashedAlgorithm::ImportKeyJwk(
- const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const {
- const char* jwk_algorithm =
- GetJwkAlgorithm(algorithm.rsaHashedImportParams()->hash().id());
-
- if (!jwk_algorithm)
- return Status::ErrorUnexpected();
-
- JwkRsaInfo jwk;
- Status status =
- ReadRsaKeyJwk(key_data, jwk_algorithm, extractable, usages, &jwk);
- if (status.IsError())
- return status;
-
- // Once the key type is known, verify the usages.
- status = CheckKeyCreationUsages(
- jwk.is_private_key ? all_private_key_usages_ : all_public_key_usages_,
- usages, !jwk.is_private_key);
- if (status.IsError())
- return status;
-
- return jwk.is_private_key
- ? ImportRsaPrivateKey(algorithm, extractable, usages, jwk, key)
- : ImportRsaPublicKey(algorithm, extractable, usages,
- CryptoData(jwk.n), CryptoData(jwk.e), key);
-}
-
-Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const {
- const char* jwk_algorithm =
- GetJwkAlgorithm(key.algorithm().rsaHashedParams()->hash().id());
-
- if (!jwk_algorithm)
- return Status::ErrorUnexpected();
-
- switch (key.type()) {
- case blink::WebCryptoKeyTypePublic: {
- SECKEYPublicKey* nss_key = PublicKeyNss::Cast(key)->key();
- if (nss_key->keyType != rsaKey)
- return Status::ErrorUnsupported();
-
- WriteRsaPublicKeyJwk(SECItemToCryptoData(nss_key->u.rsa.modulus),
- SECItemToCryptoData(nss_key->u.rsa.publicExponent),
- jwk_algorithm, key.extractable(), key.usages(),
- buffer);
-
- return Status::Success();
- }
-
- case blink::WebCryptoKeyTypePrivate: {
- SECKEYPrivateKey* nss_key = PrivateKeyNss::Cast(key)->key();
- RSAPrivateKey key_props = {};
- scoped_ptr<RSAPrivateKey, FreeRsaPrivateKey> free_private_key(&key_props);
-
- if (!InitRSAPrivateKey(nss_key, &key_props))
- return Status::OperationError();
-
- WriteRsaPrivateKeyJwk(SECItemToCryptoData(key_props.modulus),
- SECItemToCryptoData(key_props.public_exponent),
- SECItemToCryptoData(key_props.private_exponent),
- SECItemToCryptoData(key_props.prime1),
- SECItemToCryptoData(key_props.prime2),
- SECItemToCryptoData(key_props.exponent1),
- SECItemToCryptoData(key_props.exponent2),
- SECItemToCryptoData(key_props.coefficient),
- jwk_algorithm, key.extractable(), key.usages(),
- buffer);
-
- return Status::Success();
- }
- default:
- return Status::ErrorUnexpected();
- }
-}
-
-Status RsaHashedAlgorithm::SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const {
- key_data->assign(static_cast<KeyNss*>(key.handle())->serialized_key_data());
- return Status::Success();
-}
-
-// TODO(eroman): Defer import to the crypto thread. http://crbug.com/430763
-Status RsaHashedAlgorithm::DeserializeKeyForClone(
- const blink::WebCryptoKeyAlgorithm& algorithm,
- blink::WebCryptoKeyType type,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- const CryptoData& key_data,
- blink::WebCryptoKey* key) const {
- blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
- algorithm.id(), algorithm.rsaHashedParams()->hash().id());
-
- Status status;
-
- switch (type) {
- case blink::WebCryptoKeyTypePublic:
- status =
- ImportKeySpki(key_data, import_algorithm, extractable, usages, key);
- break;
- case blink::WebCryptoKeyTypePrivate:
- status =
- ImportKeyPkcs8(key_data, import_algorithm, extractable, usages, key);
- break;
- default:
- return Status::ErrorUnexpected();
- }
-
- // There is some duplicated information in the serialized format used by
- // structured clone (since the KeyAlgorithm is serialized separately from the
- // key data). Use this extra information to further validate what was
- // deserialized from the key data.
-
- if (algorithm.id() != key->algorithm().id())
- return Status::ErrorUnexpected();
-
- if (key->type() != type)
- return Status::ErrorUnexpected();
-
- if (algorithm.rsaHashedParams()->modulusLengthBits() !=
- key->algorithm().rsaHashedParams()->modulusLengthBits()) {
- return Status::ErrorUnexpected();
- }
-
- if (algorithm.rsaHashedParams()->publicExponent().size() !=
- key->algorithm().rsaHashedParams()->publicExponent().size() ||
- 0 !=
- memcmp(algorithm.rsaHashedParams()->publicExponent().data(),
- key->algorithm().rsaHashedParams()->publicExponent().data(),
- key->algorithm().rsaHashedParams()->publicExponent().size())) {
- return Status::ErrorUnexpected();
- }
-
- return Status::Success();
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/rsa_hashed_algorithm_nss.h b/chromium/components/webcrypto/nss/rsa_hashed_algorithm_nss.h
deleted file mode 100644
index ff8fbce6daf..00000000000
--- a/chromium/components/webcrypto/nss/rsa_hashed_algorithm_nss.h
+++ /dev/null
@@ -1,99 +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_WEBCRYPTO_NSS_RSA_HASHED_ALGORITHM_NSS_H_
-#define COMPONENTS_WEBCRYPTO_NSS_RSA_HASHED_ALGORITHM_NSS_H_
-
-#include <pkcs11t.h>
-
-#include "components/webcrypto/algorithm_implementation.h"
-
-namespace webcrypto {
-
-class PublicKeyNss;
-class PrivateKeyNss;
-
-// Base class for an RSA algorithm whose keys additionaly have a hash parameter
-// bound to them. Provides functionality for generating, importing, and
-// exporting keys.
-class RsaHashedAlgorithm : public AlgorithmImplementation {
- public:
- // Constructs an RSA algorithm which will use the NSS flags |generate_flags|
- // when generating keys. |all_public_key_usages| and |all_private_key_usages|
- // are the set of WebCrypto key usages that are valid for created keys
- // (public and private respectively).
- //
- // For instance if public keys support encryption and wrapping, and private
- // keys support decryption and unwrapping callers should set:
- // all_public_key_usages = UsageEncrypt | UsageWrap
- // all_private_key_usages = UsageDecrypt | UsageUnwrap
- // This information is used when importing or generating keys, to enforce
- // that valid key usages are allowed.
- RsaHashedAlgorithm(CK_FLAGS generate_flags,
- blink::WebCryptoKeyUsageMask all_public_key_usages,
- blink::WebCryptoKeyUsageMask all_private_key_usages)
- : generate_flags_(generate_flags),
- all_public_key_usages_(all_public_key_usages),
- all_private_key_usages_(all_private_key_usages) {}
-
- // For instance "RSA-OAEP-256".
- virtual const char* GetJwkAlgorithm(
- const blink::WebCryptoAlgorithmId hash) const = 0;
-
- Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- GenerateKeyResult* result) const override;
-
- Status VerifyKeyUsagesBeforeImportKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask usages) const override;
-
- Status ImportKeyPkcs8(const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const override;
-
- Status ImportKeySpki(const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const override;
-
- Status ExportKeyPkcs8(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const override;
-
- Status ExportKeySpki(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const override;
-
- Status ImportKeyJwk(const CryptoData& key_data,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key) const override;
-
- Status ExportKeyJwk(const blink::WebCryptoKey& key,
- std::vector<uint8_t>* buffer) const override;
-
- Status SerializeKeyForClone(
- const blink::WebCryptoKey& key,
- blink::WebVector<uint8_t>* key_data) const override;
-
- Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
- blink::WebCryptoKeyType type,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- const CryptoData& key_data,
- blink::WebCryptoKey* key) const override;
-
- private:
- const CK_FLAGS generate_flags_;
- const blink::WebCryptoKeyUsageMask all_public_key_usages_;
- const blink::WebCryptoKeyUsageMask all_private_key_usages_;
-};
-
-} // namespace webcrypto
-
-#endif // COMPONENTS_WEBCRYPTO_NSS_RSA_HASHED_ALGORITHM_NSS_H_
diff --git a/chromium/components/webcrypto/nss/rsa_oaep_nss.cc b/chromium/components/webcrypto/nss/rsa_oaep_nss.cc
deleted file mode 100644
index d66b6c3b4ff..00000000000
--- a/chromium/components/webcrypto/nss/rsa_oaep_nss.cc
+++ /dev/null
@@ -1,227 +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 <cryptohi.h>
-#include <keyhi.h>
-#include <pk11pub.h>
-#include <secerr.h>
-#include <sechash.h>
-
-#include "base/stl_util.h"
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/nss/key_nss.h"
-#include "components/webcrypto/nss/rsa_hashed_algorithm_nss.h"
-#include "components/webcrypto/nss/util_nss.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
-#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
-
-namespace webcrypto {
-
-namespace {
-
-Status NssSupportsRsaOaep() {
- if (NssRuntimeSupport::Get()->IsRsaOaepSupported())
- return Status::Success();
- return Status::ErrorUnsupported(
- "NSS version doesn't support RSA-OAEP. Try using version 3.16.2 or "
- "later");
-}
-
-CK_MECHANISM_TYPE WebCryptoHashToMGFMechanism(
- const blink::WebCryptoAlgorithm& algorithm) {
- switch (algorithm.id()) {
- case blink::WebCryptoAlgorithmIdSha1:
- return CKG_MGF1_SHA1;
- case blink::WebCryptoAlgorithmIdSha256:
- return CKG_MGF1_SHA256;
- case blink::WebCryptoAlgorithmIdSha384:
- return CKG_MGF1_SHA384;
- case blink::WebCryptoAlgorithmIdSha512:
- return CKG_MGF1_SHA512;
- default:
- return CKM_INVALID_MECHANISM;
- }
-}
-
-CK_MECHANISM_TYPE WebCryptoHashToDigestMechanism(
- const blink::WebCryptoAlgorithm& algorithm) {
- switch (algorithm.id()) {
- case blink::WebCryptoAlgorithmIdSha1:
- return CKM_SHA_1;
- case blink::WebCryptoAlgorithmIdSha256:
- return CKM_SHA256;
- case blink::WebCryptoAlgorithmIdSha384:
- return CKM_SHA384;
- case blink::WebCryptoAlgorithmIdSha512:
- return CKM_SHA512;
- default:
- // Not a supported algorithm.
- return CKM_INVALID_MECHANISM;
- }
-}
-
-bool InitializeRsaOaepParams(const blink::WebCryptoAlgorithm& hash,
- const CryptoData& label,
- CK_RSA_PKCS_OAEP_PARAMS* oaep_params) {
- oaep_params->source = CKZ_DATA_SPECIFIED;
- oaep_params->pSourceData = const_cast<unsigned char*>(label.bytes());
- oaep_params->ulSourceDataLen = label.byte_length();
- oaep_params->mgf = WebCryptoHashToMGFMechanism(hash);
- oaep_params->hashAlg = WebCryptoHashToDigestMechanism(hash);
-
- if (oaep_params->mgf == CKM_INVALID_MECHANISM ||
- oaep_params->hashAlg == CKM_INVALID_MECHANISM) {
- return false;
- }
-
- return true;
-}
-
-Status EncryptRsaOaep(SECKEYPublicKey* key,
- const blink::WebCryptoAlgorithm& hash,
- const CryptoData& label,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) {
- CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0};
- if (!InitializeRsaOaepParams(hash, label, &oaep_params))
- return Status::ErrorUnsupported();
-
- SECItem param;
- param.type = siBuffer;
- param.data = reinterpret_cast<unsigned char*>(&oaep_params);
- param.len = sizeof(oaep_params);
-
- buffer->resize(SECKEY_PublicKeyStrength(key));
- unsigned char* buffer_data = vector_as_array(buffer);
- unsigned int output_len;
- if (NssRuntimeSupport::Get()->pk11_pub_encrypt_func()(
- key, CKM_RSA_PKCS_OAEP, &param, buffer_data, &output_len,
- buffer->size(), data.bytes(), data.byte_length(),
- NULL) != SECSuccess) {
- return Status::OperationError();
- }
-
- CHECK_LE(output_len, buffer->size());
- buffer->resize(output_len);
- return Status::Success();
-}
-
-Status DecryptRsaOaep(SECKEYPrivateKey* key,
- const blink::WebCryptoAlgorithm& hash,
- const CryptoData& label,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) {
- Status status = NssSupportsRsaOaep();
- if (status.IsError())
- return status;
-
- CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0};
- if (!InitializeRsaOaepParams(hash, label, &oaep_params))
- return Status::ErrorUnsupported();
-
- SECItem param;
- param.type = siBuffer;
- param.data = reinterpret_cast<unsigned char*>(&oaep_params);
- param.len = sizeof(oaep_params);
-
- const int modulus_length_bytes = PK11_GetPrivateModulusLen(key);
- if (modulus_length_bytes <= 0)
- return Status::ErrorUnexpected();
-
- buffer->resize(modulus_length_bytes);
-
- unsigned char* buffer_data = vector_as_array(buffer);
- unsigned int output_len;
- if (NssRuntimeSupport::Get()->pk11_priv_decrypt_func()(
- key, CKM_RSA_PKCS_OAEP, &param, buffer_data, &output_len,
- buffer->size(), data.bytes(), data.byte_length()) != SECSuccess) {
- return Status::OperationError();
- }
-
- CHECK_LE(output_len, buffer->size());
- buffer->resize(output_len);
- return Status::Success();
-}
-
-class RsaOaepImplementation : public RsaHashedAlgorithm {
- public:
- RsaOaepImplementation()
- : RsaHashedAlgorithm(
- CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP,
- blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageWrapKey,
- blink::WebCryptoKeyUsageDecrypt |
- blink::WebCryptoKeyUsageUnwrapKey) {}
-
- Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- GenerateKeyResult* result) const override {
- Status status = NssSupportsRsaOaep();
- if (status.IsError())
- return status;
- return RsaHashedAlgorithm::GenerateKey(algorithm, extractable, usages,
- result);
- }
-
- Status VerifyKeyUsagesBeforeImportKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask usages) const override {
- Status status = NssSupportsRsaOaep();
- if (status.IsError())
- return status;
- return RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey(format, usages);
- }
-
- const char* GetJwkAlgorithm(
- const blink::WebCryptoAlgorithmId hash) const override {
- switch (hash) {
- case blink::WebCryptoAlgorithmIdSha1:
- return "RSA-OAEP";
- case blink::WebCryptoAlgorithmIdSha256:
- return "RSA-OAEP-256";
- case blink::WebCryptoAlgorithmIdSha384:
- return "RSA-OAEP-384";
- case blink::WebCryptoAlgorithmIdSha512:
- return "RSA-OAEP-512";
- default:
- return NULL;
- }
- }
-
- Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- if (key.type() != blink::WebCryptoKeyTypePublic)
- return Status::ErrorUnexpectedKeyType();
-
- return EncryptRsaOaep(
- PublicKeyNss::Cast(key)->key(),
- key.algorithm().rsaHashedParams()->hash(),
- CryptoData(algorithm.rsaOaepParams()->optionalLabel()), data, buffer);
- }
-
- Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- if (key.type() != blink::WebCryptoKeyTypePrivate)
- return Status::ErrorUnexpectedKeyType();
-
- return DecryptRsaOaep(
- PrivateKeyNss::Cast(key)->key(),
- key.algorithm().rsaHashedParams()->hash(),
- CryptoData(algorithm.rsaOaepParams()->optionalLabel()), data, buffer);
- }
-};
-
-} // namespace
-
-AlgorithmImplementation* CreatePlatformRsaOaepImplementation() {
- return new RsaOaepImplementation;
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/rsa_ssa_nss.cc b/chromium/components/webcrypto/nss/rsa_ssa_nss.cc
deleted file mode 100644
index 193bd040287..00000000000
--- a/chromium/components/webcrypto/nss/rsa_ssa_nss.cc
+++ /dev/null
@@ -1,133 +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 <cryptohi.h>
-
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/nss/key_nss.h"
-#include "components/webcrypto/nss/rsa_hashed_algorithm_nss.h"
-#include "components/webcrypto/nss/util_nss.h"
-#include "components/webcrypto/status.h"
-#include "crypto/scoped_nss_types.h"
-#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
-
-namespace webcrypto {
-
-namespace {
-
-class RsaSsaImplementation : public RsaHashedAlgorithm {
- public:
- RsaSsaImplementation()
- : RsaHashedAlgorithm(CKF_SIGN | CKF_VERIFY,
- blink::WebCryptoKeyUsageVerify,
- blink::WebCryptoKeyUsageSign) {}
-
- const char* GetJwkAlgorithm(
- const blink::WebCryptoAlgorithmId hash) const override {
- switch (hash) {
- case blink::WebCryptoAlgorithmIdSha1:
- return "RS1";
- case blink::WebCryptoAlgorithmIdSha256:
- return "RS256";
- case blink::WebCryptoAlgorithmIdSha384:
- return "RS384";
- case blink::WebCryptoAlgorithmIdSha512:
- return "RS512";
- default:
- return NULL;
- }
- }
-
- Status Sign(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- if (key.type() != blink::WebCryptoKeyTypePrivate)
- return Status::ErrorUnexpectedKeyType();
-
- SECKEYPrivateKey* private_key = PrivateKeyNss::Cast(key)->key();
-
- const blink::WebCryptoAlgorithm& hash =
- key.algorithm().rsaHashedParams()->hash();
-
- // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the
- // inner hash of the input Web Crypto algorithm.
- SECOidTag sign_alg_tag;
- switch (hash.id()) {
- case blink::WebCryptoAlgorithmIdSha1:
- sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
- break;
- case blink::WebCryptoAlgorithmIdSha256:
- sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
- break;
- case blink::WebCryptoAlgorithmIdSha384:
- sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
- break;
- case blink::WebCryptoAlgorithmIdSha512:
- sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
- break;
- default:
- return Status::ErrorUnsupported();
- }
-
- crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0));
- if (SEC_SignData(signature_item.get(), data.bytes(), data.byte_length(),
- private_key, sign_alg_tag) != SECSuccess) {
- return Status::OperationError();
- }
-
- buffer->assign(signature_item->data,
- signature_item->data + signature_item->len);
- return Status::Success();
- }
-
- Status Verify(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const CryptoData& signature,
- const CryptoData& data,
- bool* signature_match) const override {
- if (key.type() != blink::WebCryptoKeyTypePublic)
- return Status::ErrorUnexpectedKeyType();
-
- SECKEYPublicKey* public_key = PublicKeyNss::Cast(key)->key();
-
- const blink::WebCryptoAlgorithm& hash =
- key.algorithm().rsaHashedParams()->hash();
-
- const SECItem signature_item = MakeSECItemForBuffer(signature);
-
- SECOidTag hash_alg_tag;
- switch (hash.id()) {
- case blink::WebCryptoAlgorithmIdSha1:
- hash_alg_tag = SEC_OID_SHA1;
- break;
- case blink::WebCryptoAlgorithmIdSha256:
- hash_alg_tag = SEC_OID_SHA256;
- break;
- case blink::WebCryptoAlgorithmIdSha384:
- hash_alg_tag = SEC_OID_SHA384;
- break;
- case blink::WebCryptoAlgorithmIdSha512:
- hash_alg_tag = SEC_OID_SHA512;
- break;
- default:
- return Status::ErrorUnsupported();
- }
-
- *signature_match =
- SECSuccess == VFY_VerifyDataDirect(data.bytes(), data.byte_length(),
- public_key, &signature_item,
- SEC_OID_PKCS1_RSA_ENCRYPTION,
- hash_alg_tag, NULL, NULL);
- return Status::Success();
- }
-};
-
-} // namespace
-
-AlgorithmImplementation* CreatePlatformRsaSsaImplementation() {
- return new RsaSsaImplementation;
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/sha_nss.cc b/chromium/components/webcrypto/nss/sha_nss.cc
deleted file mode 100644
index 17800a16cac..00000000000
--- a/chromium/components/webcrypto/nss/sha_nss.cc
+++ /dev/null
@@ -1,156 +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 <sechash.h>
-#include <vector>
-
-#include "base/stl_util.h"
-#include "components/webcrypto/algorithm_implementation.h"
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/nss/util_nss.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-#include "crypto/nss_util.h"
-#include "crypto/scoped_nss_types.h"
-
-namespace webcrypto {
-
-namespace {
-
-HASH_HashType WebCryptoAlgorithmToNSSHashType(
- blink::WebCryptoAlgorithmId algorithm) {
- switch (algorithm) {
- case blink::WebCryptoAlgorithmIdSha1:
- return HASH_AlgSHA1;
- case blink::WebCryptoAlgorithmIdSha256:
- return HASH_AlgSHA256;
- case blink::WebCryptoAlgorithmIdSha384:
- return HASH_AlgSHA384;
- case blink::WebCryptoAlgorithmIdSha512:
- return HASH_AlgSHA512;
- default:
- // Not a digest algorithm.
- return HASH_AlgNULL;
- }
-}
-
-// Implementation of blink::WebCryptoDigester, an internal Blink detail not
-// part of WebCrypto, that allows chunks of data to be streamed in before
-// computing a SHA-* digest (as opposed to ShaImplementation, which computes
-// digests over complete messages)
-class DigestorNSS : public blink::WebCryptoDigestor {
- public:
- explicit DigestorNSS(blink::WebCryptoAlgorithmId algorithm_id)
- : hash_context_(NULL), algorithm_id_(algorithm_id) {}
-
- ~DigestorNSS() override {
- if (!hash_context_)
- return;
-
- HASH_Destroy(hash_context_);
- hash_context_ = NULL;
- }
-
- bool consume(const unsigned char* data, unsigned int size) override {
- return ConsumeWithStatus(data, size).IsSuccess();
- }
-
- Status ConsumeWithStatus(const unsigned char* data, unsigned int size) {
- // Initialize everything if the object hasn't been initialized yet.
- if (!hash_context_) {
- Status error = Init();
- if (!error.IsSuccess())
- return error;
- }
-
- HASH_Update(hash_context_, data, size);
-
- return Status::Success();
- }
-
- bool finish(unsigned char*& result_data,
- unsigned int& result_data_size) override {
- Status error = FinishInternal(result_, &result_data_size);
- if (!error.IsSuccess())
- return false;
- result_data = result_;
- return true;
- }
-
- Status FinishWithVectorAndStatus(std::vector<uint8_t>* result) {
- if (!hash_context_)
- return Status::ErrorUnexpected();
-
- unsigned int result_length = HASH_ResultLenContext(hash_context_);
- result->resize(result_length);
- unsigned char* digest = vector_as_array(result);
- unsigned int digest_size; // ignored
- return FinishInternal(digest, &digest_size);
- }
-
- private:
- Status Init() {
- HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm_id_);
-
- if (hash_type == HASH_AlgNULL)
- return Status::ErrorUnsupported();
-
- hash_context_ = HASH_Create(hash_type);
- if (!hash_context_)
- return Status::OperationError();
-
- HASH_Begin(hash_context_);
-
- return Status::Success();
- }
-
- Status FinishInternal(unsigned char* result, unsigned int* result_size) {
- if (!hash_context_) {
- Status error = Init();
- if (!error.IsSuccess())
- return error;
- }
-
- unsigned int hash_result_length = HASH_ResultLenContext(hash_context_);
- DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX));
-
- HASH_End(hash_context_, result, result_size, hash_result_length);
-
- if (*result_size != hash_result_length)
- return Status::ErrorUnexpected();
- return Status::Success();
- }
-
- HASHContext* hash_context_;
- blink::WebCryptoAlgorithmId algorithm_id_;
- unsigned char result_[HASH_LENGTH_MAX];
-};
-
-class ShaImplementation : public AlgorithmImplementation {
- public:
- Status Digest(const blink::WebCryptoAlgorithm& algorithm,
- const CryptoData& data,
- std::vector<uint8_t>* buffer) const override {
- DigestorNSS digestor(algorithm.id());
- Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length());
- // http://crbug.com/366427: the spec does not define any other failures for
- // digest, so none of the subsequent errors are spec compliant.
- if (!error.IsSuccess())
- return error;
- return digestor.FinishWithVectorAndStatus(buffer);
- }
-};
-
-} // namespace
-
-AlgorithmImplementation* CreatePlatformShaImplementation() {
- return new ShaImplementation();
-}
-
-scoped_ptr<blink::WebCryptoDigestor> CreatePlatformDigestor(
- blink::WebCryptoAlgorithmId algorithm) {
- return scoped_ptr<blink::WebCryptoDigestor>(new DigestorNSS(algorithm));
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/sym_key_nss.cc b/chromium/components/webcrypto/nss/sym_key_nss.cc
deleted file mode 100644
index cd8f7fe08bd..00000000000
--- a/chromium/components/webcrypto/nss/sym_key_nss.cc
+++ /dev/null
@@ -1,76 +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/webcrypto/nss/sym_key_nss.h"
-
-#include "base/logging.h"
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/generate_key_result.h"
-#include "components/webcrypto/nss/key_nss.h"
-#include "components/webcrypto/nss/util_nss.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-#include "crypto/scoped_nss_types.h"
-#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
-
-namespace webcrypto {
-
-Status GenerateSecretKeyNss(const blink::WebCryptoKeyAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- unsigned int keylen_bits,
- CK_MECHANISM_TYPE mechanism,
- GenerateKeyResult* result) {
- DCHECK_NE(CKM_INVALID_MECHANISM, mechanism);
-
- crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
- if (!slot)
- return Status::OperationError();
-
- std::vector<uint8_t> bytes(NumBitsToBytes(keylen_bits));
- if (bytes.size() > 0) {
- if (PK11_GenerateRandom(&bytes[0], bytes.size()) != SECSuccess)
- return Status::OperationError();
- TruncateToBitLength(keylen_bits, &bytes);
- }
-
- blink::WebCryptoKey key;
- Status status = ImportKeyRawNss(CryptoData(bytes), algorithm, extractable,
- usages, mechanism, &key);
- if (status.IsError())
- return status;
-
- result->AssignSecretKey(key);
- return Status::Success();
-}
-
-Status ImportKeyRawNss(const CryptoData& key_data,
- const blink::WebCryptoKeyAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- CK_MECHANISM_TYPE mechanism,
- blink::WebCryptoKey* key) {
- // The usages are enforced at the WebCrypto layer, so it isn't necessary to
- // create keys with limited usages.
- CK_FLAGS flags = kAllOperationFlags;
-
- DCHECK(!algorithm.isNull());
- SECItem key_item = MakeSECItemForBuffer(key_data);
-
- crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
- crypto::ScopedPK11SymKey pk11_sym_key(PK11_ImportSymKeyWithFlags(
- slot.get(), mechanism, PK11_OriginUnwrap, CKA_FLAGS_ONLY, &key_item,
- flags, false, NULL));
- if (!pk11_sym_key.get())
- return Status::OperationError();
-
- scoped_ptr<SymKeyNss> handle(new SymKeyNss(pk11_sym_key.Pass(), key_data));
-
- *key = blink::WebCryptoKey::create(handle.release(),
- blink::WebCryptoKeyTypeSecret, extractable,
- algorithm, usages);
- return Status::Success();
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/sym_key_nss.h b/chromium/components/webcrypto/nss/sym_key_nss.h
deleted file mode 100644
index 78d0acb9be1..00000000000
--- a/chromium/components/webcrypto/nss/sym_key_nss.h
+++ /dev/null
@@ -1,34 +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_WEBCRYPTO_NSS_SYM_KEY_NSS_H_
-#define COMPONENTS_WEBCRYPTO_NSS_SYM_KEY_NSS_H_
-
-#include <pkcs11t.h>
-
-#include "third_party/WebKit/public/platform/WebCrypto.h"
-
-namespace webcrypto {
-
-class CryptoData;
-class GenerateKeyResult;
-class Status;
-
-Status GenerateSecretKeyNss(const blink::WebCryptoKeyAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- unsigned int keylen_bits,
- CK_MECHANISM_TYPE mechanism,
- GenerateKeyResult* result);
-
-Status ImportKeyRawNss(const CryptoData& key_data,
- const blink::WebCryptoKeyAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- CK_MECHANISM_TYPE mechanism,
- blink::WebCryptoKey* key);
-
-} // namespace webcrypto
-
-#endif // COMPONENTS_WEBCRYPTO_NSS_SYM_KEY_NSS_H_
diff --git a/chromium/components/webcrypto/nss/util_nss.cc b/chromium/components/webcrypto/nss/util_nss.cc
deleted file mode 100644
index 784a98016ca..00000000000
--- a/chromium/components/webcrypto/nss/util_nss.cc
+++ /dev/null
@@ -1,113 +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/webcrypto/nss/util_nss.h"
-
-#include "base/lazy_instance.h"
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/platform_crypto.h"
-#include "crypto/nss_util.h"
-#include "crypto/scoped_nss_types.h"
-
-#if defined(USE_NSS_CERTS)
-#include <dlfcn.h>
-#include <secoid.h>
-#endif
-
-namespace webcrypto {
-
-namespace {
-base::LazyInstance<NssRuntimeSupport>::Leaky g_nss_runtime_support =
- LAZY_INSTANCE_INITIALIZER;
-} // namespace
-
-// Creates a SECItem for the data in |buffer|. This does NOT make a copy, so
-// |buffer| should outlive the SECItem.
-SECItem MakeSECItemForBuffer(const CryptoData& buffer) {
- SECItem item = {
- siBuffer,
- // NSS requires non-const data even though it is just for input.
- const_cast<unsigned char*>(buffer.bytes()),
- buffer.byte_length()};
- return item;
-}
-
-CryptoData SECItemToCryptoData(const SECItem& item) {
- return CryptoData(item.data, item.len);
-}
-
-NssRuntimeSupport* NssRuntimeSupport::Get() {
- return &g_nss_runtime_support.Get();
-}
-
-NssRuntimeSupport::NssRuntimeSupport() : internal_slot_does_oaep_(false) {
-#if !defined(USE_NSS_CERTS)
- // Using a bundled version of NSS that is guaranteed to have this symbol.
- pk11_encrypt_func_ = PK11_Encrypt;
- pk11_decrypt_func_ = PK11_Decrypt;
- pk11_pub_encrypt_func_ = PK11_PubEncrypt;
- pk11_priv_decrypt_func_ = PK11_PrivDecrypt;
- internal_slot_does_oaep_ = true;
-#else
- // Using system NSS libraries and PCKS #11 modules, which may not have the
- // necessary function (PK11_Encrypt) or mechanism support (CKM_AES_GCM).
-
- // If PK11_Encrypt() was successfully resolved, then NSS will support
- // AES-GCM directly. This was introduced in NSS 3.15.
- pk11_encrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>(
- dlsym(RTLD_DEFAULT, "PK11_Encrypt"));
- pk11_decrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>(
- dlsym(RTLD_DEFAULT, "PK11_Decrypt"));
-
- // Even though NSS's pk11wrap layer may support
- // PK11_PubEncrypt/PK11_PubDecrypt (introduced in NSS 3.16.2), it may have
- // loaded a softoken that does not include OAEP support.
- pk11_pub_encrypt_func_ = reinterpret_cast<PK11_PubEncryptFunction>(
- dlsym(RTLD_DEFAULT, "PK11_PubEncrypt"));
- pk11_priv_decrypt_func_ = reinterpret_cast<PK11_PrivDecryptFunction>(
- dlsym(RTLD_DEFAULT, "PK11_PrivDecrypt"));
- if (pk11_priv_decrypt_func_ && pk11_pub_encrypt_func_) {
- crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
- internal_slot_does_oaep_ =
- !!PK11_DoesMechanism(slot.get(), CKM_RSA_PKCS_OAEP);
- }
-#endif
-}
-
-void PlatformInit() {
- crypto::EnsureNSSInit();
-}
-
-AlgorithmImplementation* CreatePlatformAesCtrImplementation() {
- // TODO(eroman): http://crbug.com/399084
- return NULL;
-}
-
-AlgorithmImplementation* CreatePlatformRsaPssImplementation() {
- // TODO(eroman): http://crbug.com/399090
- return NULL;
-}
-
-AlgorithmImplementation* CreatePlatformEcdsaImplementation() {
- // TODO(eroman): http://crbug.com/399094
- return NULL;
-}
-
-AlgorithmImplementation* CreatePlatformEcdhImplementation() {
- // TODO(eroman): http://crbug.com/399093
- return NULL;
-}
-
-AlgorithmImplementation* CreatePlatformHkdfImplementation() {
- // HKDF is only being imlemented for BoringSSL.
- return NULL;
-}
-
-AlgorithmImplementation* CreatePlatformPbkdf2Implementation() {
- // PBKDF2 will only be implemented for BoringSSL, since the NSS
- // implementation is being deprecated.
- return NULL;
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/nss/util_nss.h b/chromium/components/webcrypto/nss/util_nss.h
deleted file mode 100644
index 04a44ebd184..00000000000
--- a/chromium/components/webcrypto/nss/util_nss.h
+++ /dev/null
@@ -1,112 +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_WEBCRYPTO_NSS_UTIL_NSS_H_
-#define COMPONENTS_WEBCRYPTO_NSS_UTIL_NSS_H_
-
-#include <keythi.h>
-#include <pkcs11t.h>
-#include <seccomon.h>
-#include <secmodt.h>
-
-#include "base/lazy_instance.h"
-
-namespace webcrypto {
-
-class CryptoData;
-
-SECItem MakeSECItemForBuffer(const CryptoData& buffer);
-enum EncryptOrDecrypt { ENCRYPT, DECRYPT };
-
-CryptoData SECItemToCryptoData(const SECItem& item);
-
-const CK_FLAGS kAllOperationFlags =
- CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY | CKF_WRAP | CKF_UNWRAP;
-
-// Signature for PK11_Encrypt and PK11_Decrypt.
-typedef SECStatus (*PK11_EncryptDecryptFunction)(PK11SymKey*,
- CK_MECHANISM_TYPE,
- SECItem*,
- unsigned char*,
- unsigned int*,
- unsigned int,
- const unsigned char*,
- unsigned int);
-
-// Signature for PK11_PubEncrypt
-typedef SECStatus (*PK11_PubEncryptFunction)(SECKEYPublicKey*,
- CK_MECHANISM_TYPE,
- SECItem*,
- unsigned char*,
- unsigned int*,
- unsigned int,
- const unsigned char*,
- unsigned int,
- void*);
-
-// Signature for PK11_PrivDecrypt
-typedef SECStatus (*PK11_PrivDecryptFunction)(SECKEYPrivateKey*,
- CK_MECHANISM_TYPE,
- SECItem*,
- unsigned char*,
- unsigned int*,
- unsigned int,
- const unsigned char*,
- unsigned int);
-
-// Singleton that detects whether or not AES-GCM and
-// RSA-OAEP are supported by the version of NSS being used.
-// On non-Linux platforms, Chromium embedders ship with a
-// fixed version of NSS, and these are always available.
-// However, on Linux (and ChromeOS), NSS is provided by the
-// system, and thus not all algorithms may be available
-// or be safe to use.
-class NssRuntimeSupport {
- public:
- bool IsAesGcmSupported() const {
- return pk11_encrypt_func_ && pk11_decrypt_func_;
- }
-
- bool IsRsaOaepSupported() const {
- return pk11_pub_encrypt_func_ && pk11_priv_decrypt_func_ &&
- internal_slot_does_oaep_;
- }
-
- // Returns NULL if unsupported.
- PK11_EncryptDecryptFunction pk11_encrypt_func() const {
- return pk11_encrypt_func_;
- }
-
- // Returns NULL if unsupported.
- PK11_EncryptDecryptFunction pk11_decrypt_func() const {
- return pk11_decrypt_func_;
- }
-
- // Returns NULL if unsupported.
- PK11_PubEncryptFunction pk11_pub_encrypt_func() const {
- return pk11_pub_encrypt_func_;
- }
-
- // Returns NULL if unsupported.
- PK11_PrivDecryptFunction pk11_priv_decrypt_func() const {
- return pk11_priv_decrypt_func_;
- }
-
- static NssRuntimeSupport* Get();
-
- private:
- friend struct base::DefaultLazyInstanceTraits<NssRuntimeSupport>;
-
- NssRuntimeSupport();
-
- PK11_EncryptDecryptFunction pk11_encrypt_func_;
- PK11_EncryptDecryptFunction pk11_decrypt_func_;
- PK11_PubEncryptFunction pk11_pub_encrypt_func_;
- PK11_PrivDecryptFunction pk11_priv_decrypt_func_;
- bool internal_slot_does_oaep_;
-};
-
-} // namespace webcrypto
-
-#endif // COMPONENTS_WEBCRYPTO_NSS_UTIL_NSS_H_
diff --git a/chromium/components/webcrypto/openssl/key_openssl.cc b/chromium/components/webcrypto/openssl/key_openssl.cc
deleted file mode 100644
index 60922a47a82..00000000000
--- a/chromium/components/webcrypto/openssl/key_openssl.cc
+++ /dev/null
@@ -1,62 +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/webcrypto/openssl/key_openssl.h"
-
-#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
-
-namespace webcrypto {
-
-KeyOpenSsl::KeyOpenSsl(const CryptoData& serialized_key_data)
- : serialized_key_data_(
- serialized_key_data.bytes(),
- serialized_key_data.bytes() + serialized_key_data.byte_length()) {
-}
-
-KeyOpenSsl::~KeyOpenSsl() {
-}
-
-SymKeyOpenSsl* KeyOpenSsl::AsSymKey() {
- return NULL;
-}
-
-AsymKeyOpenSsl* KeyOpenSsl::AsAsymKey() {
- return NULL;
-}
-
-SymKeyOpenSsl::~SymKeyOpenSsl() {
-}
-
-SymKeyOpenSsl* SymKeyOpenSsl::Cast(const blink::WebCryptoKey& key) {
- KeyOpenSsl* platform_key = reinterpret_cast<KeyOpenSsl*>(key.handle());
- return platform_key->AsSymKey();
-}
-
-SymKeyOpenSsl* SymKeyOpenSsl::AsSymKey() {
- return this;
-}
-
-SymKeyOpenSsl::SymKeyOpenSsl(const CryptoData& raw_key_data)
- : KeyOpenSsl(raw_key_data) {
-}
-
-AsymKeyOpenSsl::~AsymKeyOpenSsl() {
-}
-
-AsymKeyOpenSsl* AsymKeyOpenSsl::Cast(const blink::WebCryptoKey& key) {
- return reinterpret_cast<KeyOpenSsl*>(key.handle())->AsAsymKey();
-}
-
-AsymKeyOpenSsl* AsymKeyOpenSsl::AsAsymKey() {
- return this;
-}
-
-AsymKeyOpenSsl::AsymKeyOpenSsl(crypto::ScopedEVP_PKEY key,
- const CryptoData& serialized_key_data)
- : KeyOpenSsl(serialized_key_data), key_(key.Pass()) {
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/openssl/key_openssl.h b/chromium/components/webcrypto/openssl/key_openssl.h
deleted file mode 100644
index 8b5d6551569..00000000000
--- a/chromium/components/webcrypto/openssl/key_openssl.h
+++ /dev/null
@@ -1,79 +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_WEBCRYPTO_OPENSSL_KEY_OPENSSL_H_
-#define COMPONENTS_WEBCRYPTO_OPENSSL_KEY_OPENSSL_H_
-
-#include <openssl/ossl_typ.h>
-#include <stdint.h>
-#include <vector>
-
-#include "base/macros.h"
-#include "crypto/scoped_openssl_types.h"
-#include "third_party/WebKit/public/platform/WebCryptoKey.h"
-
-namespace webcrypto {
-
-class CryptoData;
-class AsymKeyOpenSsl;
-class SymKeyOpenSsl;
-
-// Base key class for all OpenSSL keys, used to safely cast between types. Each
-// key maintains a copy of its serialized form in either 'raw', 'pkcs8', or
-// 'spki' format. This is to allow structured cloning of keys synchronously from
-// the target Blink thread without having to lock access to the key.
-class KeyOpenSsl : public blink::WebCryptoKeyHandle {
- public:
- explicit KeyOpenSsl(const CryptoData& serialized_key_data);
- ~KeyOpenSsl() override;
-
- virtual SymKeyOpenSsl* AsSymKey();
- virtual AsymKeyOpenSsl* AsAsymKey();
-
- const std::vector<uint8_t>& serialized_key_data() const {
- return serialized_key_data_;
- }
-
- private:
- const std::vector<uint8_t> serialized_key_data_;
-};
-
-class SymKeyOpenSsl : public KeyOpenSsl {
- public:
- ~SymKeyOpenSsl() override;
- explicit SymKeyOpenSsl(const CryptoData& raw_key_data);
-
- static SymKeyOpenSsl* Cast(const blink::WebCryptoKey& key);
-
- SymKeyOpenSsl* AsSymKey() override;
-
- const std::vector<uint8_t>& raw_key_data() const {
- return serialized_key_data();
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(SymKeyOpenSsl);
-};
-
-class AsymKeyOpenSsl : public KeyOpenSsl {
- public:
- ~AsymKeyOpenSsl() override;
- AsymKeyOpenSsl(crypto::ScopedEVP_PKEY key,
- const CryptoData& serialized_key_data);
-
- static AsymKeyOpenSsl* Cast(const blink::WebCryptoKey& key);
-
- AsymKeyOpenSsl* AsAsymKey() override;
-
- EVP_PKEY* key() { return key_.get(); }
-
- private:
- crypto::ScopedEVP_PKEY key_;
-
- DISALLOW_COPY_AND_ASSIGN(AsymKeyOpenSsl);
-};
-
-} // namespace webcrypto
-
-#endif // COMPONENTS_WEBCRYPTO_OPENSSL_KEY_OPENSSL_H_
diff --git a/chromium/components/webcrypto/openssl/util_openssl.h b/chromium/components/webcrypto/openssl/util_openssl.h
deleted file mode 100644
index eef51a4cc87..00000000000
--- a/chromium/components/webcrypto/openssl/util_openssl.h
+++ /dev/null
@@ -1,101 +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_WEBCRYPTO_OPENSSL_UTIL_OPENSSL_H_
-#define COMPONENTS_WEBCRYPTO_OPENSSL_UTIL_OPENSSL_H_
-
-#include <string>
-#include <vector>
-
-#include <openssl/ossl_typ.h>
-
-#include "crypto/scoped_openssl_types.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
-#include "third_party/WebKit/public/platform/WebCryptoKey.h"
-
-namespace webcrypto {
-
-class CryptoData;
-class GenerateKeyResult;
-class Status;
-
-// The values of these constants correspond with the "enc" parameter of
-// EVP_CipherInit_ex(), do not change.
-enum EncryptOrDecrypt { DECRYPT = 0, ENCRYPT = 1 };
-
-const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id);
-
-// Does either encryption or decryption for an AEAD algorithm.
-// * |mode| controls whether encryption or decryption is done
-// * |aead_alg| the algorithm (for instance AES-GCM)
-// * |buffer| where the ciphertext or plaintext is written to.
-Status AeadEncryptDecrypt(EncryptOrDecrypt mode,
- const std::vector<uint8_t>& raw_key,
- const CryptoData& data,
- unsigned int tag_length_bytes,
- const CryptoData& iv,
- const CryptoData& additional_data,
- const EVP_AEAD* aead_alg,
- std::vector<uint8_t>* buffer);
-
-// Generates a random secret key of the given bit length. If the bit length is
-// not a multiple of 8, then the resulting key will have ceil(keylen_bits / 8)
-// bytes, and the "unused" bits will be set to zero. This function does not do
-// any validation checks on the provided parameters.
-Status GenerateWebCryptoSecretKey(const blink::WebCryptoKeyAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- unsigned int keylen_bits,
- GenerateKeyResult* result);
-
-// Creates a WebCrypto secret key given a the raw data. The provided |key_data|
-// will be copied into the new key. This function does not do any validation
-// checks for the provided parameters.
-Status CreateWebCryptoSecretKey(const CryptoData& key_data,
- const blink::WebCryptoKeyAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key);
-
-// Creates a WebCrypto public key given an EVP_PKEY. This step includes
-// exporting the key to SPKI format, for use by serialization later.
-Status CreateWebCryptoPublicKey(crypto::ScopedEVP_PKEY public_key,
- const blink::WebCryptoKeyAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key);
-
-// Creates a WebCrypto private key given an EVP_PKEY. This step includes
-// exporting the key to PKCS8 format, for use by serialization later.
-Status CreateWebCryptoPrivateKey(crypto::ScopedEVP_PKEY private_key,
- const blink::WebCryptoKeyAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoKey* key);
-
-// Imports SPKI bytes to an EVP_PKEY for a public key. The resulting asymmetric
-// key may be invalid, and should be verified using something like
-// RSA_check_key(). The only validation performed by this function is to ensure
-// the key type matched |expected_pkey_id|.
-Status ImportUnverifiedPkeyFromSpki(const CryptoData& key_data,
- int expected_pkey_id,
- crypto::ScopedEVP_PKEY* pkey);
-
-// Imports PKCS8 bytes to an EVP_PKEY for a private key. The resulting
-// asymmetric key may be invalid, and should be verified using something like
-// RSA_check_key(). The only validation performed by this function is to ensure
-// the key type matched |expected_pkey_id|.
-Status ImportUnverifiedPkeyFromPkcs8(const CryptoData& key_data,
- int expected_pkey_id,
- crypto::ScopedEVP_PKEY* pkey);
-
-// Allocates a new BIGNUM given a std::string big-endian representation.
-BIGNUM* CreateBIGNUM(const std::string& n);
-
-// Converts a BIGNUM to a big endian byte array.
-std::vector<uint8_t> BIGNUMToVector(const BIGNUM* n);
-
-} // namespace webcrypto
-
-#endif // COMPONENTS_WEBCRYPTO_OPENSSL_UTIL_OPENSSL_H_
diff --git a/chromium/components/webcrypto/platform_crypto.h b/chromium/components/webcrypto/platform_crypto.h
deleted file mode 100644
index fdb8cef4a71..00000000000
--- a/chromium/components/webcrypto/platform_crypto.h
+++ /dev/null
@@ -1,40 +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_WEBCRYPTO_PLATFORM_CRYPTO_H_
-#define COMPONENTS_WEBCRYPTO_PLATFORM_CRYPTO_H_
-
-#include <stdint.h>
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "third_party/WebKit/public/platform/WebCrypto.h"
-
-// The definitions for these methods lives in either nss/ or openssl/
-namespace webcrypto {
-
-class AlgorithmImplementation;
-
-void PlatformInit();
-
-scoped_ptr<blink::WebCryptoDigestor> CreatePlatformDigestor(
- blink::WebCryptoAlgorithmId algorithm);
-
-AlgorithmImplementation* CreatePlatformShaImplementation();
-AlgorithmImplementation* CreatePlatformAesCbcImplementation();
-AlgorithmImplementation* CreatePlatformAesCtrImplementation();
-AlgorithmImplementation* CreatePlatformAesGcmImplementation();
-AlgorithmImplementation* CreatePlatformAesKwImplementation();
-AlgorithmImplementation* CreatePlatformHmacImplementation();
-AlgorithmImplementation* CreatePlatformRsaOaepImplementation();
-AlgorithmImplementation* CreatePlatformRsaSsaImplementation();
-AlgorithmImplementation* CreatePlatformRsaPssImplementation();
-AlgorithmImplementation* CreatePlatformEcdsaImplementation();
-AlgorithmImplementation* CreatePlatformEcdhImplementation();
-AlgorithmImplementation* CreatePlatformHkdfImplementation();
-AlgorithmImplementation* CreatePlatformPbkdf2Implementation();
-
-} // namespace webcrypto
-
-#endif // COMPONENTS_WEBCRYPTO_PLATFORM_CRYPTO_H_
diff --git a/chromium/components/webcrypto/status.h b/chromium/components/webcrypto/status.h
index 7e0ba9790f1..94124db6ade 100644
--- a/chromium/components/webcrypto/status.h
+++ b/chromium/components/webcrypto/status.h
@@ -134,7 +134,7 @@ class Status {
// Attempted to generate an AES key with an invalid length.
static Status ErrorGenerateAesKeyLength();
- // 192-bit AES keys are valid, however unsupported.
+ // 192-bit AES keys are valid, however unsupported (http://crbug.com/533699)
static Status ErrorAes192BitUnsupported();
// The wrong key was used for the operation. For instance, a public key was
diff --git a/chromium/components/webcrypto/status_unittest.cc b/chromium/components/webcrypto/status_unittest.cc
new file mode 100644
index 00000000000..ad79136f5ef
--- /dev/null
+++ b/chromium/components/webcrypto/status_unittest.cc
@@ -0,0 +1,74 @@
+// 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 "base/stl_util.h"
+#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/test_helpers.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
+#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
+
+namespace webcrypto {
+
+namespace {
+
+// Tests several Status objects against their expected hard coded values, as
+// well as ensuring that comparison of Status objects works.
+// Comparison should take into account both the error details, as well as the
+// error type.
+TEST(WebCryptoStatusTest, Basic) {
+ // Even though the error message is the same, these should not be considered
+ // the same by the tests because the error type is different.
+ EXPECT_NE(Status::DataError(), Status::OperationError());
+ EXPECT_NE(Status::Success(), Status::OperationError());
+
+ EXPECT_EQ(Status::Success(), Status::Success());
+ EXPECT_EQ(Status::ErrorJwkMemberWrongType("kty", "string"),
+ Status::ErrorJwkMemberWrongType("kty", "string"));
+
+ Status status = Status::Success();
+
+ EXPECT_FALSE(status.IsError());
+ EXPECT_EQ("", status.error_details());
+
+ status = Status::OperationError();
+ EXPECT_TRUE(status.IsError());
+ EXPECT_EQ("", status.error_details());
+ EXPECT_EQ(blink::WebCryptoErrorTypeOperation, status.error_type());
+
+ status = Status::DataError();
+ EXPECT_TRUE(status.IsError());
+ EXPECT_EQ("", status.error_details());
+ EXPECT_EQ(blink::WebCryptoErrorTypeData, status.error_type());
+
+ status = Status::ErrorUnsupported();
+ EXPECT_TRUE(status.IsError());
+ EXPECT_EQ("The requested operation is unsupported", status.error_details());
+ EXPECT_EQ(blink::WebCryptoErrorTypeNotSupported, status.error_type());
+
+ status = Status::ErrorJwkMemberMissing("kty");
+ EXPECT_TRUE(status.IsError());
+ EXPECT_EQ("The required JWK member \"kty\" was missing",
+ status.error_details());
+ EXPECT_EQ(blink::WebCryptoErrorTypeData, status.error_type());
+
+ status = Status::ErrorJwkMemberWrongType("kty", "string");
+ EXPECT_TRUE(status.IsError());
+ EXPECT_EQ("The JWK member \"kty\" must be a string", status.error_details());
+ EXPECT_EQ(blink::WebCryptoErrorTypeData, status.error_type());
+
+ status = Status::ErrorJwkBase64Decode("n");
+ EXPECT_TRUE(status.IsError());
+ EXPECT_EQ(
+ "The JWK member \"n\" could not be base64url decoded or contained "
+ "padding",
+ status.error_details());
+ EXPECT_EQ(blink::WebCryptoErrorTypeData, status.error_type());
+}
+
+} // namespace
+
+} // namespace webcrypto
diff --git a/chromium/components/webcrypto/webcrypto.gyp b/chromium/components/webcrypto/webcrypto.gyp
index f386343e3b4..e4cf9af5507 100644
--- a/chromium/components/webcrypto/webcrypto.gyp
+++ b/chromium/components/webcrypto/webcrypto.gyp
@@ -9,120 +9,60 @@
'type': 'static_library',
'dependencies': [
'../../base/base.gyp:base',
- '../tracing.gyp:tracing',
- '../../skia/skia.gyp:skia',
- '../../ui/base/ui_base.gyp:ui_base',
- '../../ui/events/events.gyp:gestures_blink',
- '../../url/url.gyp:url_lib',
+ '../../crypto/crypto.gyp:crypto',
+ '../../third_party/boringssl/boringssl.gyp:boringssl',
+ '../../third_party/WebKit/public/blink.gyp:blink',
],
'include_dirs': [
'..',
],
- 'export_dependent_settings': [
- '../../base/base.gyp:base',
- ],
- 'variables': {
- 'webcrypto_sources': [
- 'algorithm_dispatch.cc',
- 'algorithm_dispatch.h',
- 'algorithm_implementation.cc',
- 'algorithm_implementation.h',
- 'algorithm_registry.cc',
- 'algorithm_registry.h',
- 'crypto_data.cc',
- 'crypto_data.h',
- 'generate_key_result.cc',
- 'generate_key_result.h',
- 'jwk.cc',
- 'jwk.h',
- 'platform_crypto.h',
- 'status.cc',
- 'status.h',
- 'webcrypto_impl.cc',
- 'webcrypto_impl.h',
- 'webcrypto_util.cc',
- 'webcrypto_util.h',
- ],
- 'webcrypto_nss_sources': [
- 'nss/aes_algorithm_nss.cc',
- 'nss/aes_algorithm_nss.h',
- 'nss/aes_cbc_nss.cc',
- 'nss/aes_gcm_nss.cc',
- 'nss/aes_kw_nss.cc',
- 'nss/hmac_nss.cc',
- 'nss/key_nss.cc',
- 'nss/key_nss.h',
- 'nss/rsa_hashed_algorithm_nss.cc',
- 'nss/rsa_hashed_algorithm_nss.h',
- 'nss/rsa_oaep_nss.cc',
- 'nss/rsa_ssa_nss.cc',
- 'nss/sha_nss.cc',
- 'nss/sym_key_nss.cc',
- 'nss/sym_key_nss.h',
- 'nss/util_nss.cc',
- 'nss/util_nss.h',
- ],
- 'webcrypto_openssl_sources': [
- 'openssl/aes_algorithm_openssl.cc',
- 'openssl/aes_algorithm_openssl.h',
- 'openssl/aes_cbc_openssl.cc',
- 'openssl/aes_ctr_openssl.cc',
- 'openssl/aes_gcm_openssl.cc',
- 'openssl/aes_kw_openssl.cc',
- 'openssl/ec_algorithm_openssl.cc',
- 'openssl/ec_algorithm_openssl.h',
- 'openssl/ecdh_openssl.cc',
- 'openssl/ecdsa_openssl.cc',
- 'openssl/hkdf_openssl.cc',
- 'openssl/hmac_openssl.cc',
- 'openssl/key_openssl.cc',
- 'openssl/key_openssl.h',
- 'openssl/pbkdf2_openssl.cc',
- 'openssl/rsa_hashed_algorithm_openssl.cc',
- 'openssl/rsa_hashed_algorithm_openssl.h',
- 'openssl/rsa_oaep_openssl.cc',
- 'openssl/rsa_pss_openssl.cc',
- 'openssl/rsa_sign_openssl.cc',
- 'openssl/rsa_sign_openssl.h',
- 'openssl/rsa_ssa_openssl.cc',
- 'openssl/sha_openssl.cc',
- 'openssl/util_openssl.cc',
- 'openssl/util_openssl.h',
- ],
- },
'sources': [
- '<@(webcrypto_sources)',
- ],
- 'conditions': [
- ['OS=="android"', {
- 'dependencies': [
- '../../build/android/ndk.gyp:cpu_features',
- ],
- }],
- ['use_openssl==1', {
- 'sources': [
- '<@(webcrypto_openssl_sources)',
- ],
- 'dependencies': [
- '../../third_party/boringssl/boringssl.gyp:boringssl',
- ],
- }, {
- 'sources': [
- '<@(webcrypto_nss_sources)',
- ],
- 'conditions': [
- ['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', {
- 'dependencies': [
- '../../build/linux/system.gyp:ssl',
- ],
- }, {
- 'dependencies': [
- '../../third_party/nss/nss.gyp:nspr',
- '../../third_party/nss/nss.gyp:nss',
- ],
- }],
- ],
- }],
+ 'algorithm_dispatch.cc',
+ 'algorithm_dispatch.h',
+ 'algorithm_implementation.cc',
+ 'algorithm_implementation.h',
+ 'algorithm_implementations.h',
+ 'algorithm_registry.cc',
+ 'algorithm_registry.h',
+ 'algorithms/aes.cc',
+ 'algorithms/aes.h',
+ 'algorithms/aes_cbc.cc',
+ 'algorithms/aes_ctr.cc',
+ 'algorithms/aes_gcm.cc',
+ 'algorithms/aes_kw.cc',
+ 'algorithms/asymmetric_key_util.cc',
+ 'algorithms/asymmetric_key_util.h',
+ 'algorithms/ec.cc',
+ 'algorithms/ec.h',
+ 'algorithms/ecdh.cc',
+ 'algorithms/ecdsa.cc',
+ 'algorithms/hkdf.cc',
+ 'algorithms/hmac.cc',
+ 'algorithms/pbkdf2.cc',
+ 'algorithms/rsa.cc',
+ 'algorithms/rsa.h',
+ 'algorithms/rsa_oaep.cc',
+ 'algorithms/rsa_pss.cc',
+ 'algorithms/rsa_sign.cc',
+ 'algorithms/rsa_sign.h',
+ 'algorithms/rsa_ssa.cc',
+ 'algorithms/secret_key_util.cc',
+ 'algorithms/secret_key_util.h',
+ 'algorithms/sha.cc',
+ 'algorithms/util.cc',
+ 'algorithms/util.h',
+ 'blink_key_handle.cc',
+ 'blink_key_handle.h',
+ 'crypto_data.cc',
+ 'crypto_data.h',
+ 'generate_key_result.cc',
+ 'generate_key_result.h',
+ 'jwk.cc',
+ 'jwk.h',
+ 'status.cc',
+ 'status.h',
+ 'webcrypto_impl.cc',
+ 'webcrypto_impl.h',
],
},
],
diff --git a/chromium/components/webcrypto/webcrypto_impl.cc b/chromium/components/webcrypto/webcrypto_impl.cc
index 3ccfbc912d1..71d4b2b26da 100644
--- a/chromium/components/webcrypto/webcrypto_impl.cc
+++ b/chromium/components/webcrypto/webcrypto_impl.cc
@@ -19,7 +19,6 @@
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
#include "third_party/WebKit/public/platform/WebString.h"
@@ -63,7 +62,7 @@ namespace {
// threads is silly.
//
// * WebCryptoAlgorithm and WebCryptoKey are threadsafe (however the key's
-// handle(), which wraps an NSS/OpenSSL type, may not be and should only be
+// handle(), which wraps an OpenSSL type, may not be and should only be
// used from the webcrypto thread).
//
// * blink::WebCryptoResult is not threadsafe and should only be operated on
diff --git a/chromium/components/webcrypto/webcrypto_impl.h b/chromium/components/webcrypto/webcrypto_impl.h
index 8b24b53b677..068a65cfc18 100644
--- a/chromium/components/webcrypto/webcrypto_impl.h
+++ b/chromium/components/webcrypto/webcrypto_impl.h
@@ -14,7 +14,7 @@
namespace webcrypto {
// Wrapper around the Blink WebCrypto asynchronous interface, which forwards to
-// the synchronous platform (NSS or OpenSSL) implementation.
+// the synchronous OpenSSL implementation.
//
// WebCryptoImpl is threadsafe.
//
@@ -23,79 +23,75 @@ class WebCryptoImpl : public blink::WebCrypto {
public:
WebCryptoImpl();
- // TODO(eroman): Once Blink and Chromium repositories are merged, use
- // "override" in place of virtual.
+ ~WebCryptoImpl() override;
- virtual ~WebCryptoImpl();
-
- virtual void encrypt(const blink::WebCryptoAlgorithm& algorithm,
+ void encrypt(const blink::WebCryptoAlgorithm& algorithm,
+ const blink::WebCryptoKey& key,
+ const unsigned char* data,
+ unsigned int data_size,
+ blink::WebCryptoResult result) override;
+ void decrypt(const blink::WebCryptoAlgorithm& algorithm,
+ const blink::WebCryptoKey& key,
+ const unsigned char* data,
+ unsigned int data_size,
+ blink::WebCryptoResult result) override;
+ void digest(const blink::WebCryptoAlgorithm& algorithm,
+ const unsigned char* data,
+ unsigned int data_size,
+ blink::WebCryptoResult result) override;
+ void generateKey(const blink::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoResult result) override;
+ void importKey(blink::WebCryptoKeyFormat format,
+ const unsigned char* key_data,
+ unsigned int key_data_size,
+ const blink::WebCryptoAlgorithm& algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoResult result) override;
+ void exportKey(blink::WebCryptoKeyFormat format,
+ const blink::WebCryptoKey& key,
+ blink::WebCryptoResult result) override;
+ void sign(const blink::WebCryptoAlgorithm& algorithm,
+ const blink::WebCryptoKey& key,
+ const unsigned char* data,
+ unsigned int data_size,
+ blink::WebCryptoResult result) override;
+ void verifySignature(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
+ const unsigned char* signature,
+ unsigned int signature_size,
const unsigned char* data,
unsigned int data_size,
- blink::WebCryptoResult result);
- virtual void decrypt(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const unsigned char* data,
- unsigned int data_size,
- blink::WebCryptoResult result);
- virtual void digest(const blink::WebCryptoAlgorithm& algorithm,
- const unsigned char* data,
- unsigned int data_size,
- blink::WebCryptoResult result);
- virtual void generateKey(const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoResult result);
- virtual void importKey(blink::WebCryptoKeyFormat format,
- const unsigned char* key_data,
- unsigned int key_data_size,
- const blink::WebCryptoAlgorithm& algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoResult result);
- virtual void exportKey(blink::WebCryptoKeyFormat format,
- const blink::WebCryptoKey& key,
- blink::WebCryptoResult result);
- virtual void sign(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const unsigned char* data,
- unsigned int data_size,
- blink::WebCryptoResult result);
- virtual void verifySignature(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& key,
- const unsigned char* signature,
- unsigned int signature_size,
- const unsigned char* data,
- unsigned int data_size,
- blink::WebCryptoResult result);
- virtual void wrapKey(blink::WebCryptoKeyFormat format,
- const blink::WebCryptoKey& key,
- const blink::WebCryptoKey& wrapping_key,
- const blink::WebCryptoAlgorithm& wrap_algorithm,
- blink::WebCryptoResult result);
- virtual void unwrapKey(
- blink::WebCryptoKeyFormat format,
- const unsigned char* wrapped_key,
- unsigned wrapped_key_size,
- const blink::WebCryptoKey& wrapping_key,
- const blink::WebCryptoAlgorithm& unwrap_algorithm,
- const blink::WebCryptoAlgorithm& unwrapped_key_algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoResult result);
+ blink::WebCryptoResult result) override;
+ void wrapKey(blink::WebCryptoKeyFormat format,
+ const blink::WebCryptoKey& key,
+ const blink::WebCryptoKey& wrapping_key,
+ const blink::WebCryptoAlgorithm& wrap_algorithm,
+ blink::WebCryptoResult result) override;
+ void unwrapKey(blink::WebCryptoKeyFormat format,
+ const unsigned char* wrapped_key,
+ unsigned wrapped_key_size,
+ const blink::WebCryptoKey& wrapping_key,
+ const blink::WebCryptoAlgorithm& unwrap_algorithm,
+ const blink::WebCryptoAlgorithm& unwrapped_key_algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoResult result) override;
- virtual void deriveBits(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& base_key,
- unsigned int length_bits,
- blink::WebCryptoResult result);
+ void deriveBits(const blink::WebCryptoAlgorithm& algorithm,
+ const blink::WebCryptoKey& base_key,
+ unsigned int length_bits,
+ blink::WebCryptoResult result) override;
- virtual void deriveKey(const blink::WebCryptoAlgorithm& algorithm,
- const blink::WebCryptoKey& base_key,
- const blink::WebCryptoAlgorithm& import_algorithm,
- const blink::WebCryptoAlgorithm& key_length_algorithm,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- blink::WebCryptoResult result);
+ void deriveKey(const blink::WebCryptoAlgorithm& algorithm,
+ const blink::WebCryptoKey& base_key,
+ const blink::WebCryptoAlgorithm& import_algorithm,
+ const blink::WebCryptoAlgorithm& key_length_algorithm,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ blink::WebCryptoResult result) override;
// This method returns a digestor object that can be used to synchronously
// compute a digest one chunk at a time. Thus, the consume does not need to
@@ -103,20 +99,19 @@ class WebCryptoImpl : public blink::WebCrypto {
// one at a time and the digest will be computed piecemeal. The allocated
// WebCrytpoDigestor that is returned by createDigestor must be freed by the
// caller.
- virtual blink::WebCryptoDigestor* createDigestor(
- blink::WebCryptoAlgorithmId algorithm_id);
+ blink::WebCryptoDigestor* createDigestor(
+ blink::WebCryptoAlgorithmId algorithm_id) override;
- virtual bool deserializeKeyForClone(
- const blink::WebCryptoKeyAlgorithm& algorithm,
- blink::WebCryptoKeyType type,
- bool extractable,
- blink::WebCryptoKeyUsageMask usages,
- const unsigned char* key_data,
- unsigned key_data_size,
- blink::WebCryptoKey& key);
+ bool deserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
+ blink::WebCryptoKeyType type,
+ bool extractable,
+ blink::WebCryptoKeyUsageMask usages,
+ const unsigned char* key_data,
+ unsigned key_data_size,
+ blink::WebCryptoKey& key) override;
- virtual bool serializeKeyForClone(const blink::WebCryptoKey& key,
- blink::WebVector<unsigned char>& key_data);
+ bool serializeKeyForClone(const blink::WebCryptoKey& key,
+ blink::WebVector<unsigned char>& key_data) override;
private:
DISALLOW_COPY_AND_ASSIGN(WebCryptoImpl);
diff --git a/chromium/components/webcrypto/webcrypto_util.cc b/chromium/components/webcrypto/webcrypto_util.cc
deleted file mode 100644
index 2e80c1f8afe..00000000000
--- a/chromium/components/webcrypto/webcrypto_util.cc
+++ /dev/null
@@ -1,328 +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/webcrypto/webcrypto_util.h"
-
-#include "base/logging.h"
-#include "base/numerics/safe_math.h"
-#include "components/webcrypto/status.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
-#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
-
-namespace webcrypto {
-
-namespace {
-
-// Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros,
-// to unsigned int.
-bool BigIntegerToUint(const uint8_t* data,
- size_t data_size,
- unsigned int* result) {
- if (data_size == 0)
- return false;
-
- *result = 0;
- for (size_t i = 0; i < data_size; ++i) {
- size_t reverse_i = data_size - i - 1;
-
- if (reverse_i >= sizeof(*result) && data[i])
- return false; // Too large for a uint.
-
- *result |= data[i] << 8 * reverse_i;
- }
- return true;
-}
-
-Status GetShaBlockSizeBits(const blink::WebCryptoAlgorithm& algorithm,
- unsigned int* block_size_bits) {
- switch (algorithm.id()) {
- case blink::WebCryptoAlgorithmIdSha1:
- case blink::WebCryptoAlgorithmIdSha256:
- *block_size_bits = 512;
- return Status::Success();
- case blink::WebCryptoAlgorithmIdSha384:
- case blink::WebCryptoAlgorithmIdSha512:
- *block_size_bits = 1024;
- return Status::Success();
- default:
- return Status::ErrorUnsupported();
- }
-}
-
-} // namespace
-
-blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id) {
- return blink::WebCryptoAlgorithm::adoptParamsAndCreate(id, NULL);
-}
-
-blink::WebCryptoAlgorithm CreateHmacImportAlgorithm(
- blink::WebCryptoAlgorithmId hash_id,
- unsigned int length_bits) {
- DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
- return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
- blink::WebCryptoAlgorithmIdHmac,
- new blink::WebCryptoHmacImportParams(CreateAlgorithm(hash_id), true,
- length_bits));
-}
-
-blink::WebCryptoAlgorithm CreateHmacImportAlgorithmNoLength(
- blink::WebCryptoAlgorithmId hash_id) {
- DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
- return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
- blink::WebCryptoAlgorithmIdHmac,
- new blink::WebCryptoHmacImportParams(CreateAlgorithm(hash_id), false, 0));
-}
-
-blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm(
- blink::WebCryptoAlgorithmId id,
- blink::WebCryptoAlgorithmId hash_id) {
- DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
- return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
- id, new blink::WebCryptoRsaHashedImportParams(CreateAlgorithm(hash_id)));
-}
-
-blink::WebCryptoAlgorithm CreateEcImportAlgorithm(
- blink::WebCryptoAlgorithmId id,
- blink::WebCryptoNamedCurve named_curve) {
- return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
- id, new blink::WebCryptoEcKeyImportParams(named_curve));
-}
-
-bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
- blink::WebCryptoKeyUsageMask b) {
- return (a & b) == b;
-}
-
-// TODO(eroman): Move this helper to WebCryptoKey.
-bool KeyUsageAllows(const blink::WebCryptoKey& key,
- const blink::WebCryptoKeyUsage usage) {
- return ((key.usages() & usage) != 0);
-}
-
-// The WebCrypto spec defines the default value for the tag length, as well as
-// the allowed values for tag length.
-Status GetAesGcmTagLengthInBits(const blink::WebCryptoAesGcmParams* params,
- unsigned int* tag_length_bits) {
- *tag_length_bits = 128;
- if (params->hasTagLengthBits())
- *tag_length_bits = params->optionalTagLengthBits();
-
- if (*tag_length_bits != 32 && *tag_length_bits != 64 &&
- *tag_length_bits != 96 && *tag_length_bits != 104 &&
- *tag_length_bits != 112 && *tag_length_bits != 120 &&
- *tag_length_bits != 128)
- return Status::ErrorInvalidAesGcmTagLength();
-
- return Status::Success();
-}
-
-Status GetAesKeyGenLengthInBits(const blink::WebCryptoAesKeyGenParams* params,
- unsigned int* keylen_bits) {
- *keylen_bits = params->lengthBits();
-
- if (*keylen_bits == 128 || *keylen_bits == 256)
- return Status::Success();
-
- // BoringSSL does not support 192-bit AES.
- if (*keylen_bits == 192)
- return Status::ErrorAes192BitUnsupported();
-
- return Status::ErrorGenerateAesKeyLength();
-}
-
-Status GetHmacKeyGenLengthInBits(const blink::WebCryptoHmacKeyGenParams* params,
- unsigned int* keylen_bits) {
- if (!params->hasLengthBits())
- return GetShaBlockSizeBits(params->hash(), keylen_bits);
-
- *keylen_bits = params->optionalLengthBits();
-
- // Zero-length HMAC keys are disallowed by the spec.
- if (*keylen_bits == 0)
- return Status::ErrorGenerateHmacKeyLengthZero();
-
- return Status::Success();
-}
-
-Status GetHmacImportKeyLengthBits(
- const blink::WebCryptoHmacImportParams* params,
- unsigned int key_data_byte_length,
- unsigned int* keylen_bits) {
- if (key_data_byte_length == 0)
- return Status::ErrorHmacImportEmptyKey();
-
- // Make sure that the key data's length can be represented in bits without
- // overflow.
- base::CheckedNumeric<unsigned int> checked_keylen_bits(key_data_byte_length);
- checked_keylen_bits *= 8;
-
- if (!checked_keylen_bits.IsValid())
- return Status::ErrorDataTooLarge();
-
- unsigned int data_keylen_bits = checked_keylen_bits.ValueOrDie();
-
- // Determine how many bits of the input to use.
- *keylen_bits = data_keylen_bits;
- if (params->hasLengthBits()) {
- // The requested bit length must be:
- // * No longer than the input data length
- // * At most 7 bits shorter.
- if (NumBitsToBytes(params->optionalLengthBits()) != key_data_byte_length)
- return Status::ErrorHmacImportBadLength();
- *keylen_bits = params->optionalLengthBits();
- }
-
- return Status::Success();
-}
-
-Status VerifyAesKeyLengthForImport(unsigned int keylen_bytes) {
- if (keylen_bytes == 16 || keylen_bytes == 32)
- return Status::Success();
-
- // BoringSSL does not support 192-bit AES.
- if (keylen_bytes == 24)
- return Status::ErrorAes192BitUnsupported();
-
- return Status::ErrorImportAesKeyLength();
-}
-
-Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages,
- blink::WebCryptoKeyUsageMask actual_usages,
- bool allow_empty_usages) {
- if (!allow_empty_usages && actual_usages == 0)
- return Status::ErrorCreateKeyEmptyUsages();
-
- if (!ContainsKeyUsages(all_possible_usages, actual_usages))
- return Status::ErrorCreateKeyBadUsages();
- return Status::Success();
-}
-
-Status GetRsaKeyGenParameters(
- const blink::WebCryptoRsaHashedKeyGenParams* params,
- unsigned int* public_exponent,
- unsigned int* modulus_length_bits) {
- *modulus_length_bits = params->modulusLengthBits();
-
- // Limit key sizes to those supported by NSS:
- // * Multiple of 8 bits
- // * 256 bits to 16K bits
- if (*modulus_length_bits < 256 || *modulus_length_bits > 16384 ||
- (*modulus_length_bits % 8) != 0) {
- return Status::ErrorGenerateRsaUnsupportedModulus();
- }
-
- if (!BigIntegerToUint(params->publicExponent().data(),
- params->publicExponent().size(), public_exponent)) {
- return Status::ErrorGenerateKeyPublicExponent();
- }
-
- // OpenSSL hangs when given bad public exponents, whereas NSS simply fails. To
- // avoid feeding OpenSSL data that will hang use a whitelist.
- if (*public_exponent != 3 && *public_exponent != 65537)
- return Status::ErrorGenerateKeyPublicExponent();
-
- return Status::Success();
-}
-
-Status VerifyUsagesBeforeImportAsymmetricKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask all_public_key_usages,
- blink::WebCryptoKeyUsageMask all_private_key_usages,
- blink::WebCryptoKeyUsageMask usages) {
- switch (format) {
- case blink::WebCryptoKeyFormatSpki:
- return CheckKeyCreationUsages(all_public_key_usages, usages, true);
- case blink::WebCryptoKeyFormatPkcs8:
- return CheckKeyCreationUsages(all_private_key_usages, usages, false);
- case blink::WebCryptoKeyFormatJwk: {
- // The JWK could represent either a public key or private key. The usages
- // must make sense for one of the two. The usages will be checked again by
- // ImportKeyJwk() once the key type has been determined.
- if (CheckKeyCreationUsages(all_public_key_usages, usages, true)
- .IsError() &&
- CheckKeyCreationUsages(all_private_key_usages, usages, false)
- .IsError()) {
- return Status::ErrorCreateKeyBadUsages();
- }
- return Status::Success();
- }
- default:
- return Status::ErrorUnsupportedImportKeyFormat();
- }
-}
-
-void TruncateToBitLength(size_t length_bits, std::vector<uint8_t>* bytes) {
- size_t length_bytes = NumBitsToBytes(length_bits);
-
- if (bytes->size() != length_bytes) {
- CHECK_LT(length_bytes, bytes->size());
- bytes->resize(length_bytes);
- }
-
- size_t remainder_bits = length_bits % 8;
-
- // Zero any "unused bits" in the final byte
- if (remainder_bits)
- (*bytes)[bytes->size() - 1] &= ~((0xFF) >> remainder_bits);
-}
-
-Status GetAesKeyLength(const blink::WebCryptoAlgorithm& key_length_algorithm,
- bool* has_length_bits,
- unsigned int* length_bits) {
- const blink::WebCryptoAesDerivedKeyParams* params =
- key_length_algorithm.aesDerivedKeyParams();
-
- *has_length_bits = true;
- *length_bits = params->lengthBits();
-
- if (*length_bits == 128 || *length_bits == 256)
- return Status::Success();
-
- // BoringSSL does not support 192-bit AES.
- if (*length_bits == 192)
- return Status::ErrorAes192BitUnsupported();
-
- return Status::ErrorGetAesKeyLength();
-}
-
-Status GetHmacKeyLength(const blink::WebCryptoAlgorithm& key_length_algorithm,
- bool* has_length_bits,
- unsigned int* length_bits) {
- const blink::WebCryptoHmacImportParams* params =
- key_length_algorithm.hmacImportParams();
-
- if (params->hasLengthBits()) {
- *has_length_bits = true;
- *length_bits = params->optionalLengthBits();
- if (*length_bits == 0)
- return Status::ErrorGetHmacKeyLengthZero();
- return Status::Success();
- }
-
- *has_length_bits = true;
- return GetShaBlockSizeBits(params->hash(), length_bits);
-}
-
-Status GetUsagesForGenerateAsymmetricKey(
- blink::WebCryptoKeyUsageMask combined_usages,
- blink::WebCryptoKeyUsageMask all_public_usages,
- blink::WebCryptoKeyUsageMask all_private_usages,
- blink::WebCryptoKeyUsageMask* public_usages,
- blink::WebCryptoKeyUsageMask* private_usages) {
- Status status = CheckKeyCreationUsages(all_public_usages | all_private_usages,
- combined_usages, true);
- if (status.IsError())
- return status;
-
- *public_usages = combined_usages & all_public_usages;
- *private_usages = combined_usages & all_private_usages;
-
- if (*private_usages == 0)
- return Status::ErrorCreateKeyEmptyUsages();
-
- return Status::Success();
-}
-
-} // namespace webcrypto
diff --git a/chromium/components/webcrypto/webcrypto_util.h b/chromium/components/webcrypto/webcrypto_util.h
deleted file mode 100644
index ab711ab7a2c..00000000000
--- a/chromium/components/webcrypto/webcrypto_util.h
+++ /dev/null
@@ -1,133 +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_WEBCRYPTO_WEBCRYPTO_UTIL_H_
-#define COMPONENTS_WEBCRYPTO_WEBCRYPTO_UTIL_H_
-
-#include <stdint.h>
-#include <string>
-
-#include "base/values.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
-#include "third_party/WebKit/public/platform/WebCryptoKey.h"
-
-namespace webcrypto {
-
-class Status;
-
-// Creates a WebCryptoAlgorithm without any parameters.
-blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id);
-
-// Creates an HMAC import algorithm whose inner hash algorithm is determined by
-// the specified algorithm ID. It is an error to call this method with a hash
-// algorithm that is not SHA*.
-blink::WebCryptoAlgorithm CreateHmacImportAlgorithm(
- blink::WebCryptoAlgorithmId hash_id,
- unsigned int length_bits);
-
-// Same as above but without specifying a length.
-blink::WebCryptoAlgorithm CreateHmacImportAlgorithmNoLength(
- blink::WebCryptoAlgorithmId hash_id);
-
-// Creates an import algorithm for RSA algorithms that take a hash.
-// It is an error to call this with a hash_id that is not a SHA*.
-blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm(
- blink::WebCryptoAlgorithmId id,
- blink::WebCryptoAlgorithmId hash_id);
-
-// Creates an import algorithm for EC keys.
-blink::WebCryptoAlgorithm CreateEcImportAlgorithm(
- blink::WebCryptoAlgorithmId id,
- blink::WebCryptoNamedCurve named_curve);
-
-// Returns true if the set bits in b make up a subset of the set bits in a.
-bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
- blink::WebCryptoKeyUsageMask b);
-
-bool KeyUsageAllows(const blink::WebCryptoKey& key,
- const blink::WebCryptoKeyUsage usage);
-
-Status GetAesGcmTagLengthInBits(const blink::WebCryptoAesGcmParams* params,
- unsigned int* tag_length_bits);
-
-Status GetAesKeyGenLengthInBits(const blink::WebCryptoAesKeyGenParams* params,
- unsigned int* keylen_bits);
-
-Status GetHmacKeyGenLengthInBits(const blink::WebCryptoHmacKeyGenParams* params,
- unsigned int* keylen_bits);
-
-// Gets the requested key length in bits for an HMAC import operation.
-Status GetHmacImportKeyLengthBits(
- const blink::WebCryptoHmacImportParams* params,
- unsigned int key_data_byte_length,
- unsigned int* keylen_bits);
-
-Status VerifyAesKeyLengthForImport(unsigned int keylen_bytes);
-
-Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages,
- blink::WebCryptoKeyUsageMask actual_usages,
- bool allow_empty_usages);
-
-// Extracts the public exponent and modulus length from the Blink parameters.
-// On success it is guaranteed that:
-// * public_exponent is either 3 or 65537
-// * modulus_length_bits is a multiple of 8
-// * modulus_length is >= 256
-// * modulus_length is <= 16K
-Status GetRsaKeyGenParameters(
- const blink::WebCryptoRsaHashedKeyGenParams* params,
- unsigned int* public_exponent,
- unsigned int* modulus_length_bits);
-
-// Verifies that |usages| is valid when importing a key of the given format.
-Status VerifyUsagesBeforeImportAsymmetricKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask all_public_key_usages,
- blink::WebCryptoKeyUsageMask all_private_key_usages,
- blink::WebCryptoKeyUsageMask usages);
-
-// Truncates an octet string to a particular bit length. This is accomplished by
-// resizing to the closest byte length, and then zero-ing the unused
-// least-significant bits of the final byte.
-//
-// It is an error to call this function with a bit length that is larger than
-// that of |bytes|.
-//
-// TODO(eroman): This operation is not yet defined by the WebCrypto spec,
-// however this is a reasonable interpretation:
-// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27402
-void TruncateToBitLength(size_t length_bits, std::vector<uint8_t>* bytes);
-
-// Rounds a bit count (up) to the nearest byte count.
-//
-// This is mathematically equivalent to (x + 7) / 8, however has no
-// possibility of integer overflow.
-template <typename T>
-T NumBitsToBytes(T x) {
- return (x / 8) + (7 + (x % 8)) / 8;
-}
-
-// The "get key length" operation for AES keys.
-Status GetAesKeyLength(const blink::WebCryptoAlgorithm& key_length_algorithm,
- bool* has_length_bits,
- unsigned int* length_bits);
-
-// The "get key length" operation for HMAC keys.
-Status GetHmacKeyLength(const blink::WebCryptoAlgorithm& key_length_algorithm,
- bool* has_length_bits,
- unsigned int* length_bits);
-
-// Splits the combined usages given to GenerateKey() into the respective usages
-// for the public key and private key. Returns an error if the usages are
-// invalid.
-Status GetUsagesForGenerateAsymmetricKey(
- blink::WebCryptoKeyUsageMask combined_usages,
- blink::WebCryptoKeyUsageMask all_public_usages,
- blink::WebCryptoKeyUsageMask all_private_usages,
- blink::WebCryptoKeyUsageMask* public_usages,
- blink::WebCryptoKeyUsageMask* private_usages);
-
-} // namespace webcrypto
-
-#endif // COMPONENTS_WEBCRYPTO_WEBCRYPTO_UTIL_H_
diff --git a/chromium/components/webusb.gypi b/chromium/components/webusb.gypi
new file mode 100644
index 00000000000..caf6c92064a
--- /dev/null
+++ b/chromium/components/webusb.gypi
@@ -0,0 +1,25 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'webusb',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../device/core/core.gyp:device_core',
+ '../device/usb/usb.gyp:device_usb',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'webusb/webusb_browser_client.h',
+ 'webusb/webusb_detector.cc',
+ 'webusb/webusb_detector.h',
+ ],
+ },
+ ],
+}